0.1.0 • Published 4 months ago

@joakimstai/q v0.1.0

Weekly downloads
-
License
Unlicense
Repository
github
Last release
4 months ago

Q

Size Dependencies License Maintenance

A tiny and simple FIFO queue with decent performance.

  • Simple interface
  • 342 bytes minified (204 bytes gzipped)
  • Documentation and TypeScript declarations
  • Tests and benchmarks
  • No dependencies
  • Public domain

Installation

Use your package manager of choice:

npm install @joakimstai/q
pnpm add @joakimstai/q

The library targets ES2020.

Usage

Importing

Import Q using the appropriate method for your environment:

import { Q } from '@joakimstai/q'
const { Q } = require('@joakimstai/q')

Create a queue

const queue = new Q()

Optionally, specify an array of items up front:

const queue = new Q([1, 2, 3])

Add an item to back/tail of the queue (enqueue)

queue.push(4)

Remove one item from front/head of the queue (dequeue)

queue.shift() // 1

Read any item in the queue by its index (peek)

queue.at(0)  // 2 (front)
queue.at(1)  // 3
queue.at(-1) // 4 (back)

Check the size of the queue

queue.size() // 3

Check whether the queue has any items

while (queue.hasItems()) { … // true

Get all queued items as an array

queue.toArray() // [2, 3, 4]

Reset the queue

queue.reset()

Optionally, specify an array of items to reset to:

queue.reset([1, 2, 3])

That's it.

Performance

Below are the results of benchmarks adapted from denque and fast-fifo. They were executed on JavaScriptCore with bun run, using tinybench, on a 2018 Mac Mini (3 GHz 6-Core Intel Core i5).

According to these benchmarks, Q is about 2 × faster than using Array as a makeshift queue. It's not able to match the highly optimized denque and fast-fifo libraries, but is an alternative when size is important, and it should be more than performant enough for most use cases. Pretty decent for 342 bytes.

The high margin of error on the results of Q is notable, though the results are relatively stable across runs. Benchmarking is not my strong suit, so I can't really offer an explanation or analysis. Take it for what it is. YMMV, grain of salt and all that.

bench/fifo.ts

┌───┬───────────────────┬─────────┬────────────────────┬─────────┬─────────┐
│   │ Task Name         │ ops/sec │ Average Time (ns)  │ Margin  │ Samples │
├───┼───────────────────┼─────────┼────────────────────┼─────────┼─────────┤
│ 0 │ bulk:denque       │ 56,922  │ 17567.660880000152 │ ±0.07%  │ 100000  │
│ 1 │ bulk:fifo         │ 53,502  │ 18690.82211000017  │ ±0.07%  │ 100000  │
│ 2 │ bulk:q            │ 34,965  │ 28599.61588000114  │ ±57.44% │ 100000  │
│ 3 │ bulk:array        │ 16,025  │ 62401.65270999802  │ ±0.24%  │ 100000  │
│ 4 │ individual:denque │ 57,640  │ 17348.849719997284 │ ±0.10%  │ 100000  │
│ 5 │ individual:fifo   │ 53,131  │ 18821.2484400024   │ ±0.08%  │ 100000  │
│ 6 │ individual:q      │ 30,898  │ 32364.489050003427 │ ±94.29% │ 100000  │
│ 7 │ individual:array  │ 20,632  │ 48467.935640011136 │ ±0.30%  │ 100000  │
└───┴───────────────────┴─────────┴────────────────────┴─────────┴─────────┘

bench/two-million.ts

┌───┬───────────┬────────────┬────────────────────┬─────────┬─────────┐
│   │ Task Name │ ops/sec    │ Average Time (ns)  │ Margin  │ Samples │
├───┼───────────┼────────────┼────────────────────┼─────────┼─────────┤
│ 0 │ denque    │ 11,782,944 │ 84.86842916873053  │ ±0.09%  │ 5891473 │
│ 1 │ fifo      │ 10,811,026 │ 92.49815410713445  │ ±0.12%  │ 5405514 │
│ 2 │ q         │ 9,667,354  │ 103.44091228259218 │ ±35.83% │ 4833678 │
│ 3 │ array     │ 4,366,517  │ 229.01543930422363 │ ±5.63%  │ 2183259 │
└───┴───────────┴────────────┴────────────────────┴─────────┴─────────┘
0.1.0

4 months ago