# compare — benchmark

Workload: 10_000 rows; `data` runs `.gt('val', 50)`, peers run a predicate
filter `val > 50` (none of the peers ship a one-sided range operator).
Tick rewrites one row's `val` (potentially flipping its membership).
Batch streams 1000 such ticks. Generated by [comparisons/bench/operators/compare.bench.ts](../../comparisons/bench/operators/compare.bench.ts).

| Library | Setup (ms) | Single (ms) | vs data | Batch 1000 (ms) | vs data |
|---|---:|---:|---:|---:|---:|
| **data** | 1.74 | **0.020** | — | **1.80** | — |
| svelte-store | 0.867 | 0.278 | 13.9× | 334.99 | 186× |
| react | 1.02 | 0.298 | 14.9× | 345.52 | 192× |
| rxjs | 1.05 | 0.377 | 18.9× | 306.30 | 170× |
| preact-signals | 2.63 | 0.540 | 27.0× | 49.21 | 27.3× |
| crossfilter | 5.09 | 1.29 | 64.5× | 410.76 | 228× |
| solid | 13.95 | 2.33 | 117× | 213.51 | 119× |
| mobx | 106.97 | 2.81 | 141× | 228.58 | 127× |
| vue-reactivity | 13.14 | 6.86 | 343× | 631.37 | 351× |


## How

[index.ts](index.ts) is a `RowOperator` like `filter`, but with a baked-in
literal comparison rather than a user-supplied function. Each BU2 routes
to one row's `process(value)` which evaluates `value[col]` against the
threshold; same O(1) per tick characteristics as `filter(fn)`.

Use these (`.gt` / `.lt` / `.gte` / `.lte`) when the threshold is a single
literal — and a serializable one. Use `between` when you need a two-sided
range or a reactive bound. See the
[per-operator README](README.md) for the decision table.

Run `BENCH_OPS=compare npm run bench:ops` to refresh — update this file
when the numbers change materially.
