@joakimstai/q v0.1.0
Q
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 │
└───┴───────────┴────────────┴────────────────────┴─────────┴─────────┘
4 months ago