ring buffer index

Benchmark created on


Setup

// --- config ---
const N = 100000;              // loop iters inside each test (jsPerf repeats externally)
const CAP_NONPOW2 = 1000;      // generic ring capacity
const CAP_POW2    = 1024;      // power-of-two capacity (for bitmask tests)

// Two queues so pow2/nonpow2 cases don't interfere
const qN = { head: 0, capacity: CAP_NONPOW2 };
const qP = { head: 0, capacity: CAP_POW2 };

// Global sink to defeat DCE
let sink = 0;

Test runner

Ready to run.

Testing in
TestOps/sec
ternary wrap
const q = qN; q.head = 0; const cap = q.capacity;
let acc = 0;
for (let i = 0; i < N; i++) {
  const nextHead = q.head + 1;
  q.head = nextHead === cap ? 0 : nextHead;
  acc += q.head;
}
sink += acc;
ready
modulo
const q = qN; q.head = 0; const cap = q.capacity;
let acc = 0;
for (let i = 0; i < N; i++) {
  q.head = (q.head + 1) % cap;
  acc += q.head;
}
sink += acc;
ready
pre-increment + if
const q = qN; q.head = 0; const cap = q.capacity;
let acc = 0;
for (let i = 0; i < N; i++) {
  if (++q.head === cap) q.head = 0;
  acc += q.head;
}
sink += acc;
ready
compare-subtract
const q = qN; q.head = 0; const cap = q.capacity;
let acc = 0;
for (let i = 0; i < N; i++) {
  const nh = q.head + 1;
  q.head = nh >= cap ? nh - cap : nh;
  acc += q.head;
}
sink += acc;
ready
boolean-mask subtract
const q = qN; q.head = 0; const cap = q.capacity;
let acc = 0;
for (let i = 0; i < N; i++) {
  const nh = q.head + 1;
  // (nh === cap) is 0/1; multiply by cap to subtract cap exactly at wrap
  q.head = nh - ((nh === cap) * cap);
  acc += q.head;
}
sink += acc;
ready
modulo with power-of-two capacity
const q = qP; q.head = 0; const cap = q.capacity;
let acc = 0;
for (let i = 0; i < N; i++) {
  q.head = (q.head + 1) % cap;
  acc += q.head;
}
sink += acc;
ready
bitmask
const q = qP; q.head = 0; const mask = q.capacity - 1;
let acc = 0;
for (let i = 0; i < N; i++) {
  q.head = (q.head + 1) & mask;
  acc += q.head;
}
sink += acc;
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.