Skip to content

Signals

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

The write path is the most frequently executed path in the library. These benchmarks measure reads, writes and the equality cutoff on a single signal. See Benchmarks for configuration, environment and caveats.

SignalBenchmarks

One int signal observed by Observers memos (0, 1, 8 or 64).

MethodWhat it measures
ReadA tracked read with no computation running: the read an outside caller makes.
PeekAn untracked read. Compared with Read, it shows the cost of the tracking check.
WriteA write that changes the value, so every observer is notified. With 0 observers it is the floor for a write.
WriteCutoffA write of an equal value. The equality cutoff stops it, so nothing downstream is touched.
WriteAndPropagateA write followed by reading every observer back, so it includes the recomputations the write caused. The difference from Write is the cost of propagation.

Recorded 2026-09-28. Source: Ranvier.Benchmarks.Signals.SignalBenchmarks at commit d87920f.

MethodObserversMeanErrorStdDevOp/sAllocated
Read00.2294 ns0.0173 ns0.0153 ns4,358,414,858.0-
Peek00.2074 ns0.0066 ns0.0058 ns4,822,342,533.3-
Write01.6874 ns0.0293 ns0.0245 ns592,630,946.9-
WriteCutoff01.0102 ns0.0246 ns0.0231 ns989,944,159.6-
WriteAndPropagate01.8208 ns0.0289 ns0.0256 ns549,214,973.6-
Read10.2466 ns0.0235 ns0.0220 ns4,054,727,400.7-
Peek10.2018 ns0.0052 ns0.0043 ns4,954,368,076.7-
Write12.1688 ns0.0399 ns0.0354 ns461,088,285.7-
WriteCutoff11.0125 ns0.0307 ns0.0272 ns987,618,863.1-
WriteAndPropagate13.0830 ns0.0128 ns0.0107 ns324,360,362.2-
Read80.2270 ns0.0080 ns0.0075 ns4,404,951,053.6-
Peek80.2131 ns0.0111 ns0.0104 ns4,692,999,479.0-
Write86.3612 ns0.0702 ns0.0657 ns157,203,455.5-
WriteCutoff81.0141 ns0.0253 ns0.0224 ns986,111,038.4-
WriteAndPropagate87.9569 ns0.1068 ns0.0947 ns125,676,794.1-
Read640.2227 ns0.0081 ns0.0072 ns4,490,411,024.6-
Peek640.2069 ns0.0068 ns0.0060 ns4,832,182,570.0-
Write6447.8819 ns0.3217 ns0.2686 ns20,884,713.1-
WriteCutoff641.0090 ns0.0231 ns0.0193 ns991,112,303.3-
WriteAndPropagate6457.4765 ns0.3814 ns0.3381 ns17,398,409.8-

Thread affinity

SignalBenchmarks runs each case under every ThreadAffinity, set by Affinity:

AffinityCheck on a write's entry
GuardedThe default. A thread-id comparison against the graph's owner thread.
UncheckedNone.
SerialisedEntry into the graph by the calling thread, which must run on the synchronisation context the graph was constructed on. A second thread entering at once raises.

The table above predates the parameter and shows Guarded only.

The counter scenario chain-affinity writes the head of a four-memo chain and reads the tail under each affinity. Figures are retired instructions per operation at commit e13f159, .NET 10 with tiered compilation and PGO off (see Instruction counts):

Affinityinstr/opbytes/opLibrary counters/op
Guarded2,1790MemoRecomputes 4
Unchecked2,1770MemoRecomputes 4
Serialised2,5160MemoRecomputes 4

Unchecked costs the same as Guarded: the thread-id comparison is within run-to-run noise. Serialised costs about 340 more instructions per write and read of the chain, about 15 % over Guarded. The BenchmarkDotNet timing cases for each affinity are in the suite for local runs (dotnet run --project bench/Ranvier.Benchmarks -c Release -- --filter "*SignalBenchmarks*") and have no published figure yet. The full report is e13f159.md.

EqualityBenchmarks

A reference-typed signal written with a cutoff by identity (the default) or by structural comparison (StructuralPolicy). The gap between the rows is the cost of choosing structural equality.

MethodWhat it measures
IdentityCutoffBaseline. A write stopped by identity comparison.
StructuralCutoffA write of a structurally equal value, stopped by a deep comparison.
StructuralWriteA write of a structurally different value under StructuralPolicy.

Recorded 2026-09-28. Source: Ranvier.Benchmarks.Signals.EqualityBenchmarks at commit d87920f.

MethodMeanErrorStdDevOp/sRatioRatioSDGen0AllocatedAlloc Ratio
IdentityCutoff1.391 ns0.0202 ns0.0179 ns718,789,638.3baseline--NA
StructuralCutoff5.743 ns0.1000 ns0.0886 ns174,110,032.64.13x slower0.08x--NA
StructuralWrite6.208 ns0.0609 ns0.0540 ns161,091,273.44.46x slower0.07x0.001932 BNA

The Ratio and Alloc Ratio columns, where present, compare each method with the baseline method of the same class on the same run. They describe the relative cost of two operations inside Ranvier, not a comparison with any other library.

Edit this page