Table of Contents

Windows X64 AMD Ryzen 5 7600X Threading Benchmarks

Machine Profile

Machine Specification

The benchmarks were run on the following machine:

BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8037/25H2/2025Update/HudsonValley2)
AMD Ryzen 5 7600X 4.70GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.201
[Host]    : .NET 10.0.5 (10.0.5, 10.0.526.15411), X64 RyuJIT x86-64-v4
.NET 10.0 : .NET 10.0.5 (10.0.5, 10.0.526.15411), X64 RyuJIT x86-64-v4
Job=.NET 10.0  Runtime=.NET 10.0  Toolchain=net10.0
Alloc Ratio=NA

Note: Results are machine-specific and may vary between systems. Run benchmarks locally for your specific hardware.

BenchmarkDotNet microbenchmarks for all async synchronization primitives in CryptoHives.Foundation.Threading. Benchmarks cover uncontested fast paths (0 other waiters), single-waiter async round trips (1 waiter), and high-contention scenarios (10–100 waiters). All implementations are tested with both a default CancellationToken.None and a non-cancelled CancellationToken to isolate the registration overhead.

Implementations are compared against:

  • Pooled — CryptoHives pooled ValueTask-returning implementation (the baseline, ratio = 1.00)
  • ProtoPromise — ProtoPromise zero-allocation async primitives
  • RefImpl — Simple reference implementation using TaskCompletionSource<bool> (demonstrates heap-allocating baselines)
  • Nito.AsyncEx — Nito.AsyncEx async synchronization primitives (Stephen Cleary)
  • NeoSmart — NeoSmart.AsyncLock
  • VS.Threading / NonKeyed — Microsoft.VisualStudio.Threading / non-keyed async lock variants
  • System — .NET built-in synchronization primitives (SemaphoreSlim, ReaderWriterLockSlim, CountdownEvent, Barrier, ManualResetEventSlim, ManualResetEvent, AutoResetEvent)

Highlights

Primitive vs macOS M4 Key Insight
AsyncAutoResetEvent (Set) ~35% slower System.AutoResetEvent ~4× more expensive than macOS
AsyncBarrier (1 participant) ~63% slower System.Barrier 2.8× faster than macOS at 10 participants
AsyncCountdownEvent (1 participant) ~38% slower Near parity with System.CountdownEvent
AsyncLock (single) ~10% slower ProtoPromise leads; CryptoHives SpinLock ~14× faster than System.SpinLock
AsyncManualResetEvent (SetReset) ~26% slower ManualResetEvent kernel ~4× more expensive than macOS
AsyncRWLock (reader, uncontested) ~2× slower Windows faster under contention; inverts at 1+ readers
AsyncRWLock (writer, uncontested) ~52% slower ProtoPromise leads
AsyncSemaphore ~43% slower Task continuation scheduling advantage shown in AsTask paths
Note

On Windows x64, AsTask() continuations are 2–3× faster than on Apple M4 at low contention (1–2 waiters). This reflects the Windows ThreadPool's efficient inline Task continuation scheduling (the posting overhead to the ThreadPool work queue is lower). However, under very high contention (100 waiters) the macOS M4 ValueTask path becomes faster as Windows ThreadPool scheduling saturates. For maximum throughput at all contention levels prefer AsValueTask().


AsyncLock

AsyncLock provides exclusive mutual exclusion with cancellation support. The Single benchmark measures the uncontested acquire+release cycle with no other waiters. The Multiple benchmark adds a configurable number of concurrent contending waiters.

Single (uncontested)

The uncontested benchmark is a proxy for the underlying lock and ValueTask state machine cost when the fast path does not need to suspend. On x64 RyuJIT, interlocked operations (Interlocked.Add, Interlocked.Inc) run sub-nanosecond — faster than ARM64 due to the x86 TSO memory model's more relaxed fence requirements for increment operations.

Key observations:

  • Pooled: Fastest async lock; ~10% slower than macOS M4
  • ProtoPromise: ~15% faster than Pooled (zero-allocation, no cancellation support)
  • System.Lock / lock(): both ~3–4× cheaper than async paths (no await overhead)
  • CryptoHives SpinLock: matches System.Lock speed; ~14× faster than System.SpinLock
  • Nito and NeoSmart: each allocate per-lock (320 B / 208 B respectively); in the order-of-magnitude slower range
  • Interlocked.Add / Inc: sub-nanosecond — x64 TSO memory model enables cheaper atomics than ARM64 in this micro-benchmark
Description Mean Ratio Allocated
Lock · Increment · System 0.0010 ns 0.000 -
Lock · Interlocked.Add · System 0.1764 ns 0.021 -
Lock · Interlocked.Inc · System 0.1925 ns 0.023 -
Lock · Interlocked.Exchange · System 0.5166 ns 0.062 -
Lock · Interlocked.CmpX · System 0.8476 ns 0.102 -
Lock · Lock · System 3.0566 ns 0.368 -
Lock · Lock.EnterScope · System 3.1459 ns 0.379 -
SpinLock · SpinLock · CryptoHives 3.2782 ns 0.395 -
Lock · lock() · System 4.0113 ns 0.483 -
LockAsync · AsyncLock · ProtoPromise 7.0620 ns 0.851 -
LockAsync · AsyncLock · Pooled 8.3011 ns 1.000 -
LockAsync · AsyncSemaphore · VS.Threading 15.7214 ns 1.894 -
LockAsync · SemaphoreSlim · System 16.4273 ns 1.979 -
LockAsync · AsyncLock · RefImpl 17.8237 ns 2.147 -
LockAsync · AsyncLock · NonKeyed 19.4962 ns 2.349 -
LockAsync · AsyncLock · Nito.AsyncEx 37.5934 ns 4.529 320 B
SpinWait · SpinOnce · System 41.3498 ns 4.981 -
SpinLock · SpinLock · System 44.9287 ns 5.412 -
LockAsync · AsyncLock · NeoSmart 55.3936 ns 6.673 208 B

Multiple (contended)

Key observations:

  • Pooled (ValueTask): Fastest async lock path at all contention levels
  • At 1 contender: Pooled (VT) leads; ProtoPromise ~30% slower; SemaphoreSlim ~50% slower
  • Pooled (AsTask) at 1 contender: ~2.9× faster than macOS. Windows ThreadPool inlines Task continuations more efficiently at low concurrency.
  • At 100 contenders: Pooled (VT) ~29% slower than macOS M4 for the ValueTask path at saturation
  • Pooled (AsTask) at 100 contenders with NotCancelled: Windows ~3.4× faster than macOS for asynchronous task-based paths at high contention
Description Iterations cancellationType Mean Ratio Allocated
Multiple · AsyncLock · Pooled (ValueTask) 0 None 9.944 ns 1.00 -
Multiple · AsyncLock · Pooled (Task) 0 None 10.279 ns 1.03 -
Multiple · AsyncLock · ProtoPromise 0 None 11.144 ns 1.12 -
Multiple · SemaphoreSlim · System 0 None 17.640 ns 1.77 -
Multiple · AsyncSemaphore · VS.Threading 0 None 18.594 ns 1.87 -
Multiple · AsyncLock · RefImpl 0 None 19.394 ns 1.95 -
Multiple · AsyncLock · NonKeyed 0 None 20.600 ns 2.07 -
Multiple · AsyncLock · Nito 0 None 39.078 ns 3.93 320 B
Multiple · AsyncLock · NeoSmart 0 None 58.457 ns 5.88 208 B
Multiple · AsyncLock · Pooled (ValueTask) 0 NotCancelled 10.323 ns 1.00 -
Multiple · AsyncLock · Pooled (Task) 0 NotCancelled 10.642 ns 1.03 -
Multiple · AsyncLock · ProtoPromise 0 NotCancelled 11.886 ns 1.15 -
Multiple · SemaphoreSlim · System 0 NotCancelled 17.517 ns 1.70 -
Multiple · AsyncSemaphore · VS.Threading 0 NotCancelled 19.447 ns 1.88 -
Multiple · AsyncLock · NonKeyed 0 NotCancelled 21.326 ns 2.07 -
Multiple · AsyncLock · Nito 0 NotCancelled 38.806 ns 3.76 320 B
Multiple · AsyncLock · NeoSmart 0 NotCancelled 56.755 ns 5.50 208 B
Multiple · AsyncLock · Pooled (ValueTask) 1 None 28.165 ns 1.00 -
Multiple · AsyncLock · ProtoPromise 1 None 36.486 ns 1.30 -
Multiple · SemaphoreSlim · System 1 None 42.075 ns 1.49 88 B
Multiple · AsyncSemaphore · VS.Threading 1 None 64.412 ns 2.29 168 B
Multiple · AsyncLock · RefImpl 1 None 76.101 ns 2.70 216 B
Multiple · AsyncLock · Nito 1 None 91.453 ns 3.25 728 B
Multiple · AsyncLock · NeoSmart 1 None 116.605 ns 4.14 416 B
Multiple · AsyncLock · Pooled (Task) 1 None 480.060 ns 17.05 271 B
Multiple · AsyncLock · NonKeyed 1 None 543.285 ns 19.29 352 B
Multiple · AsyncLock · Pooled (ValueTask) 1 NotCancelled 46.467 ns 1.00 -
Multiple · AsyncLock · ProtoPromise 1 NotCancelled 78.408 ns 1.69 -
Multiple · AsyncSemaphore · VS.Threading 1 NotCancelled 79.121 ns 1.70 168 B
Multiple · AsyncLock · NeoSmart 1 NotCancelled 119.281 ns 2.57 416 B
Multiple · AsyncLock · Nito 1 NotCancelled 394.059 ns 8.48 968 B
Multiple · AsyncLock · Pooled (Task) 1 NotCancelled 516.424 ns 11.12 272 B
Multiple · SemaphoreSlim · System 1 NotCancelled 565.700 ns 12.18 504 B
Multiple · AsyncLock · NonKeyed 1 NotCancelled 660.724 ns 14.22 640 B
Multiple · AsyncLock · ProtoPromise 10 None 261.829 ns 0.84 -
Multiple · SemaphoreSlim · System 10 None 270.938 ns 0.87 880 B
Multiple · AsyncLock · Pooled (ValueTask) 10 None 309.915 ns 1.00 -
Multiple · AsyncSemaphore · VS.Threading 10 None 511.846 ns 1.65 1680 B
Multiple · AsyncLock · Nito 10 None 542.904 ns 1.75 4400 B
Multiple · AsyncLock · RefImpl 10 None 619.827 ns 2.00 2160 B
Multiple · AsyncLock · NeoSmart 10 None 634.247 ns 2.05 2288 B
Multiple · AsyncLock · Pooled (Task) 10 None 3,191.047 ns 10.30 1352 B
Multiple · AsyncLock · NonKeyed 10 None 3,509.004 ns 11.32 2296 B
Multiple · AsyncLock · ProtoPromise 10 NotCancelled 466.087 ns 0.91 -
Multiple · AsyncLock · Pooled (ValueTask) 10 NotCancelled 515.058 ns 1.00 -
Multiple · AsyncLock · NeoSmart 10 NotCancelled 628.808 ns 1.22 2288 B
Multiple · AsyncSemaphore · VS.Threading 10 NotCancelled 700.242 ns 1.36 1680 B
Multiple · AsyncLock · Nito 10 NotCancelled 3,204.949 ns 6.22 6800 B
Multiple · AsyncLock · Pooled (Task) 10 NotCancelled 3,474.221 ns 6.75 1352 B
Multiple · SemaphoreSlim · System 10 NotCancelled 4,349.064 ns 8.45 3888 B
Multiple · AsyncLock · NonKeyed 10 NotCancelled 4,972.770 ns 9.66 5176 B
Multiple · AsyncLock · ProtoPromise 100 None 2,582.434 ns 0.81 -
Multiple · SemaphoreSlim · System 100 None 2,587.874 ns 0.82 8800 B
Multiple · AsyncLock · Pooled (ValueTask) 100 None 3,169.397 ns 1.00 -
Multiple · AsyncSemaphore · VS.Threading 100 None 4,740.432 ns 1.50 21120 B
Multiple · AsyncLock · Nito 100 None 5,232.310 ns 1.65 41120 B
Multiple · AsyncLock · RefImpl 100 None 6,004.082 ns 1.89 21600 B
Multiple · AsyncLock · NeoSmart 100 None 6,037.141 ns 1.91 21008 B
Multiple · AsyncLock · Pooled (Task) 100 None 34,158.735 ns 10.78 12215 B
Multiple · AsyncLock · NonKeyed 100 None 35,626.170 ns 11.24 21800 B
Multiple · AsyncLock · ProtoPromise 100 NotCancelled 4,536.588 ns 0.91 -
Multiple · AsyncLock · Pooled (ValueTask) 100 NotCancelled 4,987.139 ns 1.00 -
Multiple · AsyncLock · NeoSmart 100 NotCancelled 5,916.785 ns 1.19 21008 B
Multiple · AsyncSemaphore · VS.Threading 100 NotCancelled 6,643.265 ns 1.33 21120 B
Multiple · AsyncLock · Pooled (Task) 100 NotCancelled 33,360.289 ns 6.69 12216 B
Multiple · AsyncLock · Nito 100 NotCancelled 33,478.485 ns 6.71 65120 B
Multiple · SemaphoreSlim · System 100 NotCancelled 43,340.455 ns 8.69 37792 B
Multiple · AsyncLock · NonKeyed 100 NotCancelled 51,865.969 ns 10.40 50600 B

AsyncAutoResetEvent

AsyncAutoResetEvent releases exactly one waiter per Set() call. Three benchmarks cover: Set (no waiters — measures pure signal cost), SetThenWait (signal then immediately wait on the newly-reset event), and WaitThenSet (N waiters await then are unblocked one by one).

Set (no waiters)

Key observations:

  • Pooled and ProtoPromise: sub-nanosecond pure-signal cost
  • System.AutoResetEvent (kernel): ~320× slower than Pooled; ~4× more expensive than macOS — Windows kernel event objects carry a significantly larger overhead than Apple's mach_semaphore
Description Mean Ratio Allocated
Set · AsyncAutoReset · ProtoPromise 0.5349 ns 0.79 -
Set · AsyncAutoReset · Pooled 0.6812 ns 1.00 -
Set · AsyncAutoReset · RefImpl 4.1678 ns 6.12 -
Set · AsyncAutoReset · Nito.AsyncEx 4.2622 ns 6.26 -
Set · AutoResetEvent · System 217.0665 ns 318.79 -

SetThenWait

Signals then immediately calls WaitAsync. Because the event was just set, WaitAsync returns synchronously — measures the combined signal + synchronous check cost.

Key observations:

  • Pooled (ValueTask) and ProtoPromise: sub-10 ns combined signal + synchronous check
  • RefImpl and Nito: ~2× slower than Pooled; SetThenWait for RefImpl is slower here than macOS because Windows's TaskCompletionSource fast-path post has more overhead
Description Mean Ratio Allocated
SetThenWait · AsyncAutoReset · ProtoPromise 5.294 ns 0.84 -
SetThenWait · AsyncAutoReset · Pooled (ValueTask) 6.303 ns 1.00 -
SetThenWait · AsyncAutoReset · Pooled (AsTask) 7.069 ns 1.12 -
SetThenWait · AsyncAutoReset · Nito.AsyncEx 13.545 ns 2.15 -
SetThenWait · AsyncAutoReset · RefImpl 14.940 ns 2.37 -

WaitThenSet

N waiters call WaitAsync, then Set() is called N times from another context. Each Set/Wait round trip involves a full async scheduling cycle (suspend + resume).

Key observations:

  • Pooled (AsValueTask) at 1 waiter: ~25% slower than macOS; the continuation dispatch overhead through ValueTask pooling is slightly more expensive on x64 vs ARM64 for single-waiter
  • Pooled (AsTask) at 1 waiter: ~2.75× faster than macOS for the Task path; ThreadPool Task scheduling is faster at low concurrency on Windows
  • At 100 waiters None: Pooled (VT) ~25% slower than macOS for the ValueTask path at saturation
  • Nito at 100 waiters NotCancelled: tens of microseconds — scales linearly with per-waiter CancellationToken registration
Description Iterations cancellationType Mean Ratio Allocated
WaitThenSet · AsyncAutoReset · ProtoPromise 1 None 23.11 ns 0.92 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 1 None 23.12 ns 0.92 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 1 None 23.21 ns 0.92 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 1 None 25.04 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 1 None 25.11 ns 1.00 -
WaitThenSet · AsyncAutoReset · RefImpl 1 None 27.91 ns 1.11 96 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 1 None 33.73 ns 1.34 160 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 1 None 35.44 ns 1.41 80 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 1 None 447.19 ns 17.81 231 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 1 NotCancelled 38.70 ns 0.96 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 1 NotCancelled 38.71 ns 0.96 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 1 NotCancelled 40.22 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 1 NotCancelled 40.32 ns 1.00 -
WaitThenSet · AsyncAutoReset · ProtoPromise 1 NotCancelled 44.87 ns 1.11 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 1 NotCancelled 58.77 ns 1.46 80 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 1 NotCancelled 303.38 ns 7.53 400 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 1 NotCancelled 492.10 ns 12.21 232 B
WaitThenSet · AsyncAutoReset · RefImpl 2 None 52.17 ns 0.84 192 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 2 None 56.13 ns 0.91 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 2 None 57.55 ns 0.93 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 2 None 60.42 ns 0.98 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 2 None 61.89 ns 1.00 -
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 2 None 62.63 ns 1.01 320 B
WaitThenSet · AsyncAutoReset · ProtoPromise 2 None 87.36 ns 1.41 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 2 None 91.08 ns 1.47 160 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 2 None 753.69 ns 12.18 343 B
WaitThenSet · AsyncAutoReset · ProtoPromise 2 NotCancelled 88.06 ns 0.91 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 2 NotCancelled 92.75 ns 0.96 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 2 NotCancelled 94.59 ns 0.98 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 2 NotCancelled 96.28 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 2 NotCancelled 96.54 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 2 NotCancelled 138.99 ns 1.44 160 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 2 NotCancelled 583.75 ns 6.05 800 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 2 NotCancelled 873.77 ns 9.05 344 B
WaitThenSet · AsyncAutoReset · ProtoPromise 10 None 233.91 ns 0.59 -
WaitThenSet · AsyncAutoReset · RefImpl 10 None 268.65 ns 0.68 960 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 10 None 303.53 ns 0.76 1600 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 10 None 312.26 ns 0.79 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 10 None 317.88 ns 0.80 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 10 None 342.02 ns 0.86 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 10 None 397.56 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 10 None 514.99 ns 1.30 800 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 10 None 2,049.85 ns 5.16 1236 B
WaitThenSet · AsyncAutoReset · ProtoPromise 10 NotCancelled 437.31 ns 0.85 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 10 NotCancelled 491.00 ns 0.96 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 10 NotCancelled 496.15 ns 0.97 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 10 NotCancelled 513.49 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 10 NotCancelled 515.71 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 10 NotCancelled 751.00 ns 1.46 800 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 10 NotCancelled 2,627.47 ns 5.12 4000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 10 NotCancelled 2,716.97 ns 5.29 1238 B
WaitThenSet · AsyncAutoReset · ProtoPromise 100 None 2,202.94 ns 0.66 -
WaitThenSet · AsyncAutoReset · RefImpl 100 None 2,686.45 ns 0.81 9600 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 100 None 2,922.77 ns 0.88 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 100 None 2,947.52 ns 0.89 -
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 100 None 3,133.24 ns 0.94 16000 B
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 100 None 3,296.53 ns 0.99 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 100 None 3,323.51 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 100 None 4,866.06 ns 1.46 8000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 100 None 15,749.32 ns 4.74 11320 B
WaitThenSet · AsyncAutoReset · ProtoPromise 100 NotCancelled 4,322.77 ns 0.85 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 100 NotCancelled 4,821.08 ns 0.95 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 100 NotCancelled 4,975.09 ns 0.98 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 100 NotCancelled 5,076.02 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 100 NotCancelled 5,438.26 ns 1.07 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 100 NotCancelled 7,519.64 ns 1.48 8000 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 100 NotCancelled 33,761.27 ns 6.65 40000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 100 NotCancelled 407,038.78 ns 80.20 11326 B

AsyncManualResetEvent

AsyncManualResetEvent releases all waiters when set and stays set until explicitly reset. The SetReset benchmark measures the rapid set/reset cycle. SetThenWait measures a set followed by a synchronous wait. WaitThenSet drives N concurrent waiters through a broadcast release.

SetReset

Key observations:

  • Pooled: ~2.8× faster than ManualResetEventSlim.Set+Reset
  • ManualResetEvent (kernel): ~210× slower than Pooled; ~4× more expensive than macOS — Windows kernel event objects are significantly heavier
  • ProtoPromise leads at the lowest absolute cost
Description Mean Ratio Allocated
SetReset · AsyncManualReset · ProtoPromise 1.424 ns 0.70 -
SetReset · AsyncManualReset · Pooled 2.043 ns 1.00 -
SetReset · ManualResetEventSlim · System 5.633 ns 2.76 -
SetReset · AsyncManualReset · RefImpl 10.499 ns 5.14 96 B
SetReset · AsyncManualReset · Nito.AsyncEx 17.007 ns 8.33 96 B
SetReset · ManualResetEvent · System 426.864 ns 208.98 -

SetThenWait

Description Mean Ratio Allocated
SetThenWait · AsyncManualReset · ProtoPromise 6.130 ns 0.71 -
SetThenWait · AsyncManualReset · Pooled (ValueTask) 8.679 ns 1.00 -
SetThenWait · AsyncManualReset · Pooled (AsTask) 10.352 ns 1.19 -
SetThenWait · AsyncManualReset · RefImpl 14.084 ns 1.62 96 B
SetThenWait · AsyncManualReset · Nito.AsyncEx 24.532 ns 2.83 96 B

WaitThenSet

Because AsyncManualResetEvent broadcasts to all waiters from a single Set(), RefImpl uses one TaskCompletionSource shared across all waiters — its allocation stays constant at 96 B regardless of waiter count. This gives it an unusual cost profile.

Key observations:

  • Pooled (AsValueTask) at 1 waiter: ~36% slower than macOS; this is one of the scenarios where the x64 ValueTask dispatch is slower than ARM64
  • Pooled (AsTask) at 1 waiter: ~2.9× faster than macOS for Task path
  • At 100 waiters None: Pooled (VT) ~30% slower than macOS; broadcast release at high contention favours Apple Silicon
  • Nito at 100 waiters NotCancelled: tens of microseconds — Windows ~23% faster than macOS; the Nito CancellationToken.Register scales with thread count and Windows ThreadPool completes registrations faster
Description Iterations cancellationType Mean Ratio Allocated
WaitThenSet · AsyncManualReset · RefImpl 1 None 21.77 ns 0.85 96 B
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 1 None 23.40 ns 0.92 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 1 None 24.13 ns 0.94 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 1 None 25.07 ns 0.98 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 1 None 25.56 ns 1.00 -
WaitThenSet · AsyncManualReset · ProtoPromise 1 None 26.57 ns 1.04 -
WaitThenSet · AsyncManualReset · Nito.AsyncEx 1 None 28.83 ns 1.13 96 B
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 1 None 36.29 ns 1.42 80 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 1 None 442.78 ns 17.33 231 B
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 1 NotCancelled 38.68 ns 0.94 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 1 NotCancelled 40.45 ns 0.99 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 1 NotCancelled 40.63 ns 0.99 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 1 NotCancelled 41.05 ns 1.00 -
WaitThenSet · AsyncManualReset · ProtoPromise 1 NotCancelled 49.45 ns 1.21 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 1 NotCancelled 60.87 ns 1.48 80 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 1 NotCancelled 492.64 ns 12.01 232 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 1 NotCancelled 650.27 ns 15.85 808 B
WaitThenSet · AsyncManualReset · RefImpl 2 None 26.16 ns 0.46 96 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 2 None 39.16 ns 0.69 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 2 None 46.20 ns 0.81 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 2 None 51.22 ns 0.90 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 2 None 53.31 ns 0.93 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 2 None 54.87 ns 0.96 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 2 None 57.20 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 2 None 82.64 ns 1.45 160 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 2 None 714.79 ns 12.50 343 B
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 2 NotCancelled 89.91 ns 0.96 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 2 NotCancelled 91.04 ns 0.97 -
WaitThenSet · AsyncManualReset · ProtoPromise 2 NotCancelled 91.89 ns 0.98 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 2 NotCancelled 93.81 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 2 NotCancelled 95.38 ns 1.02 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 2 NotCancelled 129.08 ns 1.38 160 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 2 NotCancelled 803.51 ns 8.57 344 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 2 NotCancelled 1,185.20 ns 12.64 1488 B
WaitThenSet · AsyncManualReset · RefImpl 10 None 64.93 ns 0.20 96 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 10 None 110.41 ns 0.34 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 10 None 214.27 ns 0.66 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 10 None 298.82 ns 0.92 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 10 None 300.43 ns 0.93 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 10 None 324.51 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 10 None 325.91 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 10 None 453.70 ns 1.40 800 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 10 None 1,971.93 ns 6.08 1239 B
WaitThenSet · AsyncManualReset · ProtoPromise 10 NotCancelled 454.68 ns 0.88 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 10 NotCancelled 482.97 ns 0.94 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 10 NotCancelled 497.87 ns 0.97 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 10 NotCancelled 515.24 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 10 NotCancelled 531.65 ns 1.03 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 10 NotCancelled 737.97 ns 1.43 800 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 10 NotCancelled 3,031.89 ns 5.88 1240 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 10 NotCancelled 4,436.31 ns 8.61 6464 B
WaitThenSet · AsyncManualReset · RefImpl 100 None 533.53 ns 0.15 96 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 100 None 928.28 ns 0.27 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 100 None 2,275.95 ns 0.65 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 100 None 2,857.04 ns 0.82 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 100 None 2,901.30 ns 0.83 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 100 None 3,161.49 ns 0.91 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 100 None 3,482.75 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 100 None 4,674.61 ns 1.34 8000 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 100 None 15,704.57 ns 4.51 11320 B
WaitThenSet · AsyncManualReset · ProtoPromise 100 NotCancelled 4,415.36 ns 0.88 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 100 NotCancelled 4,908.97 ns 0.98 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 100 NotCancelled 4,971.60 ns 0.99 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 100 NotCancelled 4,996.67 ns 0.99 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 100 NotCancelled 5,026.19 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 100 NotCancelled 7,174.00 ns 1.43 8000 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 100 NotCancelled 115,582.83 ns 23.00 61617 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 100 NotCancelled 263,666.83 ns 52.46 11327 B

AsyncSemaphore

AsyncSemaphore manages a counted resource permit (here initialized to 1). The single-permit benchmark measures the wait+release cycle uncontested (the permit is available on entry).

Key observations:

  • Pooled: ~43% slower than macOS for the uncontested path
  • ProtoPromise: leads across all configurations
  • System.SemaphoreSlim: ~85% slower than Pooled; macOS equivalent is ~25% cheaper due to lighter kernel semaphore
  • RefImpl: Windows TaskCompletionSource creation is ~55% more expensive than on macOS
Description Mean Ratio Allocated
WaitRelease · AsyncSemaphore · ProtoPromise 6.506 ns 0.71 -
WaitRelease · AsyncSemaphore · Pooled 9.162 ns 1.00 -
WaitRelease · AsyncSemaphore · Nito.AsyncEx 14.745 ns 1.61 -
WaitRelease · SemaphoreSlim · System 16.958 ns 1.85 -
WaitRelease · AsyncSemaphore · RefImpl 18.116 ns 1.98 -

AsyncCountdownEvent

AsyncCountdownEvent completes when signaled N times. Two scenarios are benchmarked: SignalAndWait where the last signal also observes the countdown reaching zero, and WaitAndSignal where a waiter is already blocking.

Key observations:

  • Pooled at P=1: ~38% slower than macOS
  • System.CountdownEvent: virtually identical on both platforms; kernel countdown objects normalize across architectures
  • At P=10: Pooled near-identical on both platforms; contention equalizes them
  • ProtoPromise consistently leads or matches System.CountdownEvent at both P=1 and P=10
Description ParticipantCount Mean Ratio Allocated
SignalAndWait · CountdownEvent · System 1 6.661 ns 0.83 -
SignalAndWait · AsyncCountdownEv · ProtoPromise 1 7.370 ns 0.92 -
SignalAndWait · AsyncCountdownEv · Pooled 1 8.016 ns 1.00 -
SignalAndWait · AsyncCountdownEv · RefImpl 1 15.803 ns 1.97 96 B
WaitAndSignal · AsyncCountdownEv · ProtoPromise 1 18.378 ns 2.29 -
WaitAndSignal · AsyncCountdownEv · Pooled 1 43.926 ns 5.48 -
SignalAndWait · AsyncCountdownEv · ProtoPromise 10 17.067 ns 0.77 -
SignalAndWait · CountdownEvent · System 10 20.834 ns 0.94 -
SignalAndWait · AsyncCountdownEv · Pooled 10 22.233 ns 1.00 -
WaitAndSignal · AsyncCountdownEv · ProtoPromise 10 28.077 ns 1.26 -
SignalAndWait · AsyncCountdownEv · RefImpl 10 28.195 ns 1.27 96 B
WaitAndSignal · AsyncCountdownEv · Pooled 10 57.694 ns 2.60 -

AsyncBarrier

AsyncBarrier blocks all N participants until all have signaled, then releases them simultaneously.

Key observations:

  • Pooled at P=1: ~63% slower than macOS; largest uncontested gap across all primitives
  • System.Barrier at P=1: ~42× slower than Pooled; ~2.4× faster than macOSSystem.Barrier uses a spin-wait strategy that performs better on x64 than macOS at low participant counts
  • At P=10: Pooled ~30% slower than macOS; System.Barrier ~2.8× slower on Windows at P=10 — the x86 spin-wait amplifies context switching cost as participant count grows
Description ParticipantCount Mean Ratio Allocated
SignalAndWait · AsyncBarrier · Pooled 1 10.85 ns 1.00 -
SignalAndWait · Barrier · System 1 452.84 ns 41.73 238 B
SignalAndWait · AsyncBarrier · RefImpl 1 936.26 ns 86.29 8347 B
SignalAndWait · AsyncBarrier · Pooled 10 254.53 ns 1.00 -
SignalAndWait · AsyncBarrier · RefImpl 10 1,667.41 ns 6.55 10252 B
SignalAndWait · Barrier · System 10 40,505.19 ns 159.16 1446 B

AsyncReaderWriterLock

AsyncReaderWriterLock supports multiple concurrent readers or a single exclusive writer, plus an upgradeable reader that can atomically promote to writer.

WriterLock (uncontested)

Key observations:

  • Pooled: ~52% slower than macOS; the writer lock has more bookkeeping than simple exclusion locks, amplifying the ARM64 JIT advantage
  • ProtoPromise: leads Pooled (~20% faster)
  • System.ReaderWriterLockSlim: ~½ the cost of Pooled; ~50% slower than macOS equivalent
  • VS.Threading: async overhead model (~100× vs Pooled); ~30% faster than macOS
Description Mean Ratio Allocated
WriterLock · RWLockSlim · System 6.905 ns 0.66 -
WriterLock · AsyncRWLock · Proto.Promises 8.379 ns 0.80 -
WriterLock · AsyncRWLock · Pooled 10.460 ns 1.00 -
WriterLock · AsyncRWLock · RefImpl 18.797 ns 1.80 -
WriterLock · AsyncRWLock · Nito.AsyncEx 54.581 ns 5.22 496 B
WriterLock · AsyncRWLock · VS.Threading 1,027.868 ns 98.27 584 B

ReaderLock

The reader lock benchmark shows a contention inversion from macOS:

  • Uncontested (0 concurrent readers): macOS ~2× faster; the uncontested reader lock path on ARM64 is exceptionally efficient
  • 1 concurrent reader: Windows ~32% faster with a single contending reader; the Windows ThreadPool schedules the read-lock resume continuation faster at low concurrency
  • 100 concurrent readers: Windows ~2× faster at high contention; the Pooled reader lock's internal structure for multi-reader scheduling benefits from the Windows ThreadPool's scalable task dispatching
  • ProtoPromise at 100 readers: dramatically different scaling ratios between platforms; macOS ProtoPromise handles the broadcast release with far fewer overheads
Description Iterations cancellationType Mean Ratio Allocated
ReaderLock · RWLockSlim · System 0 None 6.774 ns 0.40 -
ReaderLock · AsyncRWLock · Pooled 0 None 17.075 ns 1.00 -
ReaderLock · AsyncRWLock · Proto.Promises 0 None 18.400 ns 1.08 -
ReaderLock · AsyncRWLock · RefImpl 0 None 18.917 ns 1.11 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 0 None 40.428 ns 2.37 320 B
ReaderLock · AsyncRWLock · VS.Threading 0 None 224.937 ns 13.17 208 B
ReaderLock · AsyncRWLock · Pooled 0 NotCancelled 16.943 ns 1.00 -
ReaderLock · AsyncRWLock · Proto.Promises 0 NotCancelled 18.193 ns 1.07 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 0 NotCancelled 39.961 ns 2.36 320 B
ReaderLock · AsyncRWLock · VS.Threading 0 NotCancelled 224.973 ns 13.28 208 B
ReaderLock · RWLockSlim · System 1 None 12.461 ns 0.36 -
ReaderLock · AsyncRWLock · Proto.Promises 1 None 28.467 ns 0.82 -
ReaderLock · AsyncRWLock · Pooled 1 None 34.709 ns 1.00 -
ReaderLock · AsyncRWLock · RefImpl 1 None 34.977 ns 1.01 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 1 None 84.985 ns 2.45 640 B
ReaderLock · AsyncRWLock · VS.Threading 1 None 518.755 ns 14.95 416 B
ReaderLock · AsyncRWLock · Proto.Promises 1 NotCancelled 28.772 ns 0.84 -
ReaderLock · AsyncRWLock · Pooled 1 NotCancelled 34.054 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 1 NotCancelled 81.086 ns 2.38 640 B
ReaderLock · AsyncRWLock · VS.Threading 1 NotCancelled 518.476 ns 15.23 416 B
ReaderLock · RWLockSlim · System 10 None 61.761 ns 0.31 -
ReaderLock · AsyncRWLock · Proto.Promises 10 None 142.806 ns 0.72 -
ReaderLock · AsyncRWLock · RefImpl 10 None 144.870 ns 0.74 -
ReaderLock · AsyncRWLock · Pooled 10 None 197.022 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 10 None 481.419 ns 2.44 3520 B
ReaderLock · AsyncRWLock · VS.Threading 10 None 3,703.521 ns 18.80 2288 B
ReaderLock · AsyncRWLock · Proto.Promises 10 NotCancelled 147.119 ns 0.74 -
ReaderLock · AsyncRWLock · Pooled 10 NotCancelled 197.696 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 10 NotCancelled 473.137 ns 2.39 3520 B
ReaderLock · AsyncRWLock · VS.Threading 10 NotCancelled 3,614.872 ns 18.29 2288 B
ReaderLock · RWLockSlim · System 100 None 559.414 ns 0.33 -
ReaderLock · AsyncRWLock · RefImpl 100 None 1,220.891 ns 0.72 -
ReaderLock · AsyncRWLock · Proto.Promises 100 None 1,236.741 ns 0.73 -
ReaderLock · AsyncRWLock · Pooled 100 None 1,700.744 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 100 None 4,495.417 ns 2.64 32320 B
ReaderLock · AsyncRWLock · VS.Threading 100 None 87,591.125 ns 51.50 21008 B
ReaderLock · AsyncRWLock · Proto.Promises 100 NotCancelled 1,256.133 ns 0.74 -
ReaderLock · AsyncRWLock · Pooled 100 NotCancelled 1,698.319 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 100 NotCancelled 4,403.054 ns 2.59 32320 B
ReaderLock · AsyncRWLock · VS.Threading 100 NotCancelled 86,857.592 ns 51.14 21008 B

UpgradeableReaderLock

Same inversion pattern as the plain reader lock:

  • Uncontested: macOS ~2× faster
  • 1–2 concurrent upgradeables: Windows is faster (~10–37%)
  • VS.Threading upgradeable: allocates 616 B per acquire; slowest by far at all contention levels
Description Iterations cancellationType Mean Ratio Allocated
UpgradeableReaderLock · RWLockSlim · System 0 None 6.855 ns 0.43 -
UpgradeableReaderLock · AsyncRWLock · Pooled 0 None 15.959 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 0 None 20.142 ns 1.26 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 0 None 1,096.171 ns 68.69 616 B
UpgradeableReaderLock · AsyncRWLock · Pooled 0 NotCancelled 16.321 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 0 NotCancelled 18.987 ns 1.16 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 0 NotCancelled 1,127.899 ns 69.11 616 B
UpgradeableReaderLock · RWLockSlim · System 1 None 6.745 ns 0.37 -
UpgradeableReaderLock · AsyncRWLock · Pooled 1 None 18.139 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 1 None 19.333 ns 1.07 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 1 None 1,089.110 ns 60.04 616 B
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 1 NotCancelled 17.789 ns 0.90 -
UpgradeableReaderLock · AsyncRWLock · Pooled 1 NotCancelled 19.749 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 1 NotCancelled 1,138.793 ns 57.77 616 B
UpgradeableReaderLock · RWLockSlim · System 2 None 6.822 ns 0.37 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 2 None 17.518 ns 0.96 -
UpgradeableReaderLock · AsyncRWLock · Pooled 2 None 18.268 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 2 None 1,082.163 ns 59.24 616 B
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 2 NotCancelled 17.317 ns 0.93 -
UpgradeableReaderLock · AsyncRWLock · Pooled 2 NotCancelled 18.599 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 2 NotCancelled 1,124.084 ns 60.44 616 B
UpgradeableReaderLock · RWLockSlim · System 5 None 24.061 ns 0.35 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 5 None 54.872 ns 0.80 -
UpgradeableReaderLock · AsyncRWLock · Pooled 5 None 68.248 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 5 None 2,631.592 ns 38.56 1240 B
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 5 NotCancelled 53.997 ns 0.80 -
UpgradeableReaderLock · AsyncRWLock · Pooled 5 NotCancelled 67.902 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 5 NotCancelled 2,693.549 ns 39.67 1240 B

UpgradedWriterLock

The upgraded writer acquires an upgradeable read lock then promotes to exclusive writer, draining all active readers first.

  • Uncontested: macOS ~32% faster
  • 1 concurrent upgraded writer: Windows ~30% faster (same inversion as Reader at 1 contender); the Windows ThreadPool inline-completes the queued upgrade faster
  • 5 concurrent upgraded writers: Windows ~2.5× faster; the writer upgrade queue is the starkest scenario where Windows ThreadPool's Task scheduling advantage over macOS is most visible
Description Iterations cancellationType Mean Ratio Allocated
UpgradedWriterLock · RWLockSlim · System 0 None 13.46 ns 0.60 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 0 None 21.66 ns 0.97 -
UpgradedWriterLock · AsyncRWLock · Pooled 0 None 22.44 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 0 None 1,823.37 ns 81.24 824 B
UpgradedWriterLock · AsyncRWLock · Pooled 0 NotCancelled 22.76 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 0 NotCancelled 24.61 ns 1.08 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 0 NotCancelled 1,910.35 ns 83.95 824 B
UpgradedWriterLock · RWLockSlim · System 1 None 20.15 ns 0.41 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 1 None 43.06 ns 0.87 -
UpgradedWriterLock · AsyncRWLock · Pooled 1 None 49.25 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 1 None 2,325.23 ns 47.21 1032 B
UpgradedWriterLock · AsyncRWLock · Pooled 1 NotCancelled 60.90 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 1 NotCancelled 70.48 ns 1.16 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 1 NotCancelled 2,406.80 ns 39.52 1032 B
UpgradedWriterLock · RWLockSlim · System 2 None 25.36 ns 0.37 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 2 None 54.15 ns 0.80 -
UpgradedWriterLock · AsyncRWLock · Pooled 2 None 68.01 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 2 None 2,823.31 ns 41.56 1240 B
UpgradedWriterLock · AsyncRWLock · Pooled 2 NotCancelled 76.14 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 2 NotCancelled 86.37 ns 1.13 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 2 NotCancelled 2,948.51 ns 38.73 1240 B
UpgradedWriterLock · RWLockSlim · System 5 None 41.38 ns 0.33 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 5 None 92.94 ns 0.75 -
UpgradedWriterLock · AsyncRWLock · Pooled 5 None 123.96 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 5 None 4,468.96 ns 36.05 1864 B
UpgradedWriterLock · AsyncRWLock · Proto.Promises 5 NotCancelled 116.85 ns 0.90 -
UpgradedWriterLock · AsyncRWLock · Pooled 5 NotCancelled 130.50 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 5 NotCancelled 4,578.74 ns 35.09 1864 B