Skip to content

Benchmarks

vitest bench, Apple Silicon, seeded PRNG. Array sizes: 100, 1K, 10K, 100K.


pipe(data, A.filter(x => x > threshold), A.map(x => x * 2), A.take(10))

All three operations fuse into a single loop. take(10) halts after 10 results. The loop never visits the rest of the array.

9xfilter→map→take(10) on 100K elements

stopcock holds ~4M ops/s from n=100 to n=100K (the flat line). Every other library degrades linearly because they make three separate passes and allocate intermediate arrays. At 100K elements, native JS does 703 ops/s. Fusion does 4.2M.

Partial fusion: filter → map → sort → take

Section titled “Partial fusion: filter → map → sort → take”
pipe(data, A.filter(x => x > 0), A.map(x => x * 2), A.sortBy((a, b) => a - b), A.take(5))

sort can’t fuse because it needs the full array. filter → map fuses into one loop, materializes the result, then sort runs, then take slices.

The advantage shrinks because sort dominates the runtime. But partial fusion still helps. The fused filter → map segment avoids an intermediate array and runs in one pass before handing off to sort.

Outside of fused chains, stopcock still competes on raw single-op speed.




ts-belt falls over at n=10K. O(n²) implementation.