Skip to content

Instruction counts

Preview — Ranvier is pre-release; its APIs and these figures may change.

The counter bench measures whole scenarios rather than single primitives: creating and disposing rows, propagating writes, projections, application-shaped workloads, graph shapes and async boundaries. Each figure is retired processor instructions per operation, (m(2N) − m(N)) / N, read from hardware counters. Instruction counts are steadier than time, so a change of more than about 5 % is a real change in work done.

Each panel scales from zero to its largest bar, so bar lengths compare engines within a scenario, not scenarios with each other.

.NET

.NET 10.0.12, with tiered compilation, PGO and ReadyToRun off. Ranvier at e13f159, FSharp.Data.Adaptive 1.2.27, R3 1.3.1.

Instructions per operation under .NET

Fable under Node.js

Node.js v26.7.0 (--expose-gc --single-threaded), fable-library-js 5.18.0. Ranvier at e13f159, Fable.Ripple 1.0.0-beta.5. Bars are main-thread figures.

Instructions per operation under Node.js

Scenarios with a negative figure (derive-effect, derive-on, shape-dynamic, async-recover) do less work per operation than Node's run-to-run noise and show no bar.

Wave B scenarios

Seven scenarios measure Ranvier alone, on .NET only. A scenario with variants reports each variant as its own bar.

ScenarioOne operationVariants
chain-affinityWrite the source of a chain of 4 memos and read the tail.Guarded, Unchecked, Serialised
project-churnReplace the last key of a 1000-row projection with a new key.No key reader; one key reader read by an effect
flightWrite an async memo's trigger and read it, twice, then settle every flight the writes started.CancelPrevious, KeepLatest, Queue, FinishCurrent
fail-recomputeRe-run a memo and its one reader, then read the reader's ErrorOrigin.Succeeding; failing with a fresh exception
editable-editEdit every 10th of 1000 editables, each read by one effect.—
editable-upstreamWrite the seed source of every 10th of 1000 editables.—
mvu-dispatchChange one field of a 64-field model with one reader per field.A signal per field; Mvu.Dispatch with a Select per field

The .NET chart includes these scenarios. Bars are colored by engine, and a scenario's variants share their engine's color.

Reading the charts

  • Engines differ in semantics. R3 pushes each write straight to its subscribers, without batching or glitch-free ordering. FSharp.Data.Adaptive disposal removes callback subscriptions only.
  • .NET and Node figures do not compare. The .NET worker runs with PGO off; V8 optimises adaptively.

The full report, with cycles, branch misses, allocations and library counters per scenario, is docs/.ai/benchmarks/counters/e13f159.md in the repository.

Edit this page