• Stars
    star
    716
  • Rank 63,241 (Top 2 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The fastest JavaScript priority queue out there. Zero dependencies.

Heapify

codecov travis version

๐Ÿš‘ ๐Ÿšด ๐ŸšŒ ๐Ÿš• ๐Ÿš— ๐Ÿšš ๐Ÿš›

A very fast JavaScript priority queue, implemented using a binary heap, which in turn is implemented using two underlying parallel typed arrays. No dependencies whatsoever; just plain, vanilla JS.

import {MinQueue} from "heapify";
// const {MinQueue} = require("heapify");  // alternatively, require() also works

const queue = new MinQueue();
queue.push(1, 10);
queue.push(2, 5);
queue.pop();  // 2
queue.peek();  // 1
queue.clear();
queue.pop();  // undefined

It's the fastest publicly available JavaScript library implementation of a priority queue. Here's a benchmark comparing Heapify to other popular libraries:

Operation Closure FlatQueue TinyQueue Heapify
build 201 n/a n/a 18
push 222 66 75 24
pop 496 137 917 110
push/pop batch 279 83 280 89
push/pop interleaved 315 50 265 34
push/pop random 186 50 257 48

See the benchmark section for more details.

Heapify's design strives for reliability, with strong test coverage and focus on code readability. It should be easy to understand what the library is doing. The library is also very lean, with no dependencies and a small and concise source code.

Table of contents

Features

Supported queue operations:

  • push: O(log n)
  • pop: O(log n) in the general case, O(1) if not preceded by a pop
  • peek: O(1) in the general case, O(log n) if preceded by a pop
  • peekPriority: O(1) in the general case, O(log n) if preceded by a pop
  • creation with pre-existing list of priorities: O(n)

Other features:

  • runs on browser and Node.js with ES5 and ES6 support
  • tiny code base (under 200 LoC)
  • no runtime dependencies
  • supports several types of priorities and keys

How to install

npm i heapify

Or if you're a yarn person:

yarn add heapify

How to import

Node.js

You can import it in your Node.js project using TypeScript:

import {MinQueue} from "heapify";

Or directly via native ES6 module support, using the mjs ES6 module bundle:

import {MinQueue} from "heapify/heapify.mjs";

Or just require() it in your good old CommonJS project:

const {MinQueue} = require("heapify");

Browser

Heapify can be included via regular script tags, where Heapify will be exposed globally:

<script src="https://unpkg.com/heapify"></script>
<script>
  const {MinQueue} = Heapify;
</script>

The example above uses unpkg, but you can of course reference a local copy installed either manually or via npm/yarn.

For projects using native ES6 modules, make sure to import the mjs ES6 module bundle instead:

import {MinQueue} from "https://unpkg.com/heapify/heapify.mjs"

API

constructor(capacity = 64, keys = [], priorities = [], KeysBackingArrayType = Uint32Array, PrioritiesBackingArrayType = Uint32Array)

Creates a new priority queue. Parameters are:

  • capacity: the size of the underlying typed arrays backing the heap;
  • keys: an optional array of pre-existing keys. Provide [] to skip this field;
  • priorities: an optional array of pre-existing priorities. Must match number of keys above. Provide [] to skip this field;
  • KeysBackingArrayType: the array type to be used for keys;
  • PrioritiesBackingArrayType: the array type to be used for priorities.

Example:

const queue1 = new MinQueue(32);
const queue2 = new MinQueue(16, [], [], Uint16Array, Uint32Array);

capacity

A read-only property that returns the maximum capacity of the queue. Example:

const queue = new MinQueue(32);
queue.capacity;  // 32

clear()

Effectively empties the queue. The heap capacity is not changed, nor its elements get erased in any way; it's just the variable that tracks the length that gets cleared to zero, so it's a very cheap operation.

Example:

const queue = new MinQueue();
queue.push(1, 10);
console.info(queue.size);  // 1
queue.clear();
console.info(queue.size);  // 0

peek()

Gets the key with the smallest priority, but does not remove it from the queue.

Example:

const queue = new MinQueue();
queue.push(1, 10);
queue.peek();  // 1

peekPriority()

Gets the priority of the key with the smallest priority, but does not remove the item from the queue.

Example:

const queue = new MinQueue();
queue.push(1, 10);
queue.peekPriority();  // 10

pop()

Removes the smallest priority item from the queue, returning its key. Returns undefined if the queue is empty.

Note that Heapify's heap implementation is not stable. If multiple keys have the same priority, there are no guarantees about the order in which they will be popped.

Example:

const queue = new MinQueue();
queue.push(1, 10);
queue.pop();  // 1

push(key, priority)

Adds a new item to the queue with a given key and priority. Will throw an error if the queue is already at its capacity.

Example:

const queue = new MinQueue();
queue.push(1, 10);
queue.size;  // 1
queue.peek();  // 1
queue.peekPriority();  // 10

size

A read-only property that returns the current size of the queue.

Example:

const queue = new MinQueue();
queue.size;  // 0
queue.push(1, 10);
queue.size;  // 1
queue.pop();
queue.size;  // 0

Benchmark

Here's a table comparing Heapify with other implementations (times are in milliseconds):

                             Closure     FastPQ  FlatQueue  TinyQueue    Heapify
build                            201         15          -          -         18
push                             222         47         66         75         24
pop                              496        143        137        917        110
push/pop batch                   279        128         83        280         89
push/pop interleaved             315         65         50        265         34
push/pop random                  186         45         50        257         48

Host machine: Node.js 13.8.0, 2.6 GHz 6-Core Intel Core i7, 32 GB 2400 MHz DDR4 RAM.

Operations:

  • build - build queue from scratch by providing a collection of keys and priorities, all at once;
  • push - insert a single element into the queue;
  • pop - remove a single element from the queue;
  • push/pop batch - performs batches of 1k pushes followed by 1k pops;
  • push/pop interleaved - starting with a partially filled queue, this test inserts a random element and then immediately removes the lowest priority value from the queue;
  • push/pop random - starting with a partially filled queue, this test runs either a push or a pop at random.

Each test performs 1 million operations and is repeated 5 times. The median value is used as the result.

Tested libraries:

  • Google Closure library - a hugely popular library, but is the worst implementation with respect to performance;
  • Fast Priority Queue - runs comparably fast, but doesn't support inserting keys as well, so its implementation significantly limits what the user is able to achieve with it;
  • FlatQueue and TinyQueue - two very nice queue implementations by Vladimir Agafonkin. They don't support the build method and that's why they're missing this benchmark. FlatQueue performs considerably well for an implementation that is not based on typed arrays.

Contributing

You are welcome to contribute, but please take the time to read and follow these guidelines.

More Repositories

1

witchcraft

Inject Javascript and CSS right from your file system. Think GreaseMonkey for more advanced users.
JavaScript
257
star
2

chladni

Chladni plate simulation made with vanilla Javascript.
JavaScript
48
star
3

markdown-toc

Online markdown table of contents generator
HTML
45
star
4

country-flags

Display flag images based on ISO country codes.
HTML
34
star
5

socketio-with-express

Sample script demonstrating how to run Express with socket.io.
JavaScript
31
star
6

itermoxyl

Tool to automatically open multiple ssh connections in iTerm2 by querying ~/.ssh/config.
Python
30
star
7

ingresso

See movie session seat maps right from your console window!
JavaScript
13
star
8

flow-field

Playing with a vector field in HTML5 canvas using vanilla Javascript.
JavaScript
11
star
9

youtube-takeout-analyzer

JavaScript
10
star
10

magicavoxel-threejs-howto

Loading MagicaVoxel models in Three.js
HTML
10
star
11

rock-paper-automaton

A cellular automaton that plays rock paper scissors.
JavaScript
10
star
12

fit

Javascript client-side FIT file analyzer.
JavaScript
10
star
13

graham-scan

A JavaScript implementation of the Graham scan algorithm for finding the convex hull of a set of points.
JavaScript
9
star
14

binary-sse

Using server-sent events to send binary data.
JavaScript
6
star
15

java-simple-system-info

A very simple class showing how to obtain system information from inside a Java application.
Java
6
star
16

namely-org-chart

Simple script to load Namely org chart into a d3 tree layout.
TypeScript
5
star
17

pdfhacker

A low-level PDF file parser (still a work in progress).
JavaScript
5
star
18

doobie

A minimalist two-way data-binding library for those that are looking for something leaner than big fat frameworks like Angular.js.
JavaScript
5
star
19

water

Cellular automata water flow simulation running on the GPU
JavaScript
4
star
20

template-typescript-rollup

Code to use as the initial structure for developing web apps.
JavaScript
4
star
21

tree

A space-colonized growing tree.
JavaScript
4
star
22

UOMachine

Keeping this abandoned project alive.
C#
4
star
23

youtube-list-channel-videos

Simple script to fetch the list of all videos uploaded to a given YouTube channel.
JavaScript
3
star
24

easyhook

Fork of the official EasyHook project.
C
3
star
25

caparzo

A lean JavaScript library with easy-to-use pan & zoom for canvas elements on both mobile and desktop platforms.
JavaScript
3
star
26

chaos

A simulation of the chaos game.
JavaScript
3
star
27

willie

A companion to Winston
JavaScript
3
star
28

web-graphics-comparison

This is a very crude performance test to compare different approaches to visualizing 10k graphic elements on the screen.
JavaScript
3
star
29

cols-and-rows

When grep is not enough... transform text input, line by line, using regular expressions.
Python
3
star
30

escher

Generative art inspired by Escher (WIP).
JavaScript
2
star
31

socketio-with-restify

Fully functional example showing how to run socket.io with restify.
JavaScript
2
star
32

sally

Checks status of repositories in all directories.
Python
2
star
33

tcptop

Just like top, but for TCP sockets.
Python
2
star
34

particles

Particle simulation experiment using P5.js
JavaScript
2
star
35

pixi-live-map

Using pixi.js to load a live map with thousands of moving elements.
JavaScript
2
star
36

torrent-file-viewer

Drag and drop to see a torrent file's contents.
JavaScript
2
star
37

spiral

The beauty of a prime spiral.
JavaScript
2
star
38

nuclear

Generative art playing with the concept of strong interaction (aka nuclear) forces.
JavaScript
2
star
39

boleto

Analyzes bar codes of some Brazilian companies' bills.
JavaScript
2
star
40

noise

Experimenting with noise to generate terrain.
JavaScript
2
star
41

mouse

Simple online app to test malfunctioning mouses.
HTML
2
star
42

exchange-rate-scraper

Simple scraper to get euro exchange rates from sources like Transferwise, Remessa Online, etc.
JavaScript
1
star
43

climb

Compare some of the most famous cyclist climbs.
JavaScript
1
star
44

node-examples

JavaScript
1
star
45

karplus

Karplus-Strong synthesis (or how to simulate the sound of plucked strings with white noise).
JavaScript
1
star
46

rush-hour

Particles following predetermined paths.
JavaScript
1
star
47

tats

stat multiple files
JavaScript
1
star
48

udp-perf-js

JavaScript
1
star
49

vertx-lettuce-redis-client

A Redis client implemented with Lettuce using Vert.x.
Java
1
star
50

golfer

Online Javascript code golfer
HTML
1
star
51

canvas-cpu-benchmark

Things I learned while developing visualizations in the HTML canvas.
JavaScript
1
star
52

galton

Simulation of a Galton board.
JavaScript
1
star
53

uofiddler

UO Fiddler Git Repository
C#
1
star
54

razor

Razor Assistant
C#
1
star
55

protobuf-memory-optimizations

Simple experiment to show how reusing objects can hugely decrease the number memory allocations needed to handle protobuf messages.
Java
1
star
56

java-nio-tcp-perf

Java NIO TCP load and performance test.
Java
1
star
57

redis-nodejs-test

JavaScript
1
star
58

epoch

Experimental timeline plugin using d3.js
TypeScript
1
star
59

ansi

JavaScript
1
star
60

cambio

A simple Electron app to display current dollar conversion rates.
JavaScript
1
star
61

unlike

Shows differences between two directories
JavaScript
1
star
62

gear

Calculate gear ratios of your bike.
HTML
1
star
63

git-file-line-count-history

Simple script to track how the size of a specific file in a git repository changed across time.
JavaScript
1
star