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.8655/25H2/2025Update/HudsonValley2)
AMD Ryzen 5 7600X 4.70GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.301
[Host]    : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4
.NET 10.0 : .NET 10.0.9 (10.0.9, 10.0.926.27113), 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.0057 ns 0.001 -
Lock · Interlocked.Add · System 0.1939 ns 0.030 -
Lock · Interlocked.Inc · System 0.1952 ns 0.030 -
Lock · Interlocked.Exchange · System 0.5068 ns 0.078 -
Lock · Interlocked.CmpX · System 0.8521 ns 0.132 -
Lock · Lock · System 3.1394 ns 0.485 -
Lock · Lock.EnterScope · System 3.1720 ns 0.490 -
SpinLock · SpinLock · CryptoHives 3.3182 ns 0.513 -
Lock · lock() · System 3.9953 ns 0.617 -
LockAsync · AsyncLock · Pooled 6.4720 ns 1.000 -
LockAsync · AsyncLock · ProtoPromise 7.3760 ns 1.140 -
LockAsync · AsyncSemaphore · VS.Threading 16.1348 ns 2.493 -
LockAsync · SemaphoreSlim · System 16.3141 ns 2.521 -
LockAsync · AsyncLock · RefImpl 17.8354 ns 2.756 -
LockAsync · AsyncLock · NonKeyed 19.9833 ns 3.088 -
LockAsync · AsyncLock · Nito.AsyncEx 39.0541 ns 6.034 320 B
SpinWait · SpinOnce · System 42.1704 ns 6.516 -
SpinLock · SpinLock · System 45.3120 ns 7.001 -
LockAsync · AsyncLock · NeoSmart 56.5801 ns 8.742 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.524 ns 1.00 -
Multiple · AsyncLock · Pooled (Task) 0 None 11.026 ns 1.16 -
Multiple · AsyncLock · ProtoPromise 0 None 11.636 ns 1.22 -
Multiple · SemaphoreSlim · System 0 None 17.688 ns 1.86 -
Multiple · AsyncSemaphore · VS.Threading 0 None 18.970 ns 1.99 -
Multiple · AsyncLock · RefImpl 0 None 19.118 ns 2.01 -
Multiple · AsyncLock · NonKeyed 0 None 21.376 ns 2.24 -
Multiple · AsyncLock · Nito 0 None 44.416 ns 4.66 320 B
Multiple · AsyncLock · NeoSmart 0 None 58.186 ns 6.11 208 B
Multiple · AsyncLock · Pooled (ValueTask) 0 NotCancelled 9.580 ns 1.00 -
Multiple · AsyncLock · Pooled (Task) 0 NotCancelled 10.904 ns 1.14 -
Multiple · AsyncLock · ProtoPromise 0 NotCancelled 11.922 ns 1.24 -
Multiple · SemaphoreSlim · System 0 NotCancelled 17.639 ns 1.84 -
Multiple · AsyncSemaphore · VS.Threading 0 NotCancelled 19.830 ns 2.07 -
Multiple · AsyncLock · NonKeyed 0 NotCancelled 22.728 ns 2.37 -
Multiple · AsyncLock · Nito 0 NotCancelled 39.177 ns 4.09 320 B
Multiple · AsyncLock · NeoSmart 0 NotCancelled 58.758 ns 6.13 208 B
Multiple · AsyncLock · Pooled (ValueTask) 1 None 30.312 ns 1.00 -
Multiple · AsyncLock · ProtoPromise 1 None 38.128 ns 1.26 -
Multiple · SemaphoreSlim · System 1 None 43.053 ns 1.42 88 B
Multiple · AsyncSemaphore · VS.Threading 1 None 71.197 ns 2.35 168 B
Multiple · AsyncLock · RefImpl 1 None 76.606 ns 2.53 216 B
Multiple · AsyncLock · Nito 1 None 98.038 ns 3.23 728 B
Multiple · AsyncLock · NeoSmart 1 None 118.103 ns 3.90 416 B
Multiple · AsyncLock · Pooled (Task) 1 None 467.260 ns 15.42 272 B
Multiple · AsyncLock · NonKeyed 1 None 537.478 ns 17.73 352 B
Multiple · AsyncLock · Pooled (ValueTask) 1 NotCancelled 48.928 ns 1.00 -
Multiple · AsyncLock · ProtoPromise 1 NotCancelled 68.091 ns 1.39 -
Multiple · AsyncSemaphore · VS.Threading 1 NotCancelled 82.251 ns 1.68 168 B
Multiple · AsyncLock · NeoSmart 1 NotCancelled 121.842 ns 2.49 416 B
Multiple · AsyncLock · Nito 1 NotCancelled 381.676 ns 7.80 968 B
Multiple · AsyncLock · Pooled (Task) 1 NotCancelled 513.639 ns 10.50 272 B
Multiple · SemaphoreSlim · System 1 NotCancelled 597.392 ns 12.21 504 B
Multiple · AsyncLock · NonKeyed 1 NotCancelled 696.758 ns 14.24 640 B
Multiple · AsyncLock · ProtoPromise 10 None 270.858 ns 0.81 -
Multiple · SemaphoreSlim · System 10 None 283.837 ns 0.85 880 B
Multiple · AsyncLock · Pooled (ValueTask) 10 None 335.026 ns 1.00 -
Multiple · AsyncSemaphore · VS.Threading 10 None 526.298 ns 1.57 1680 B
Multiple · AsyncLock · Nito 10 None 553.332 ns 1.65 4400 B
Multiple · AsyncLock · NeoSmart 10 None 635.329 ns 1.90 2288 B
Multiple · AsyncLock · RefImpl 10 None 654.051 ns 1.95 2160 B
Multiple · AsyncLock · Pooled (Task) 10 None 3,158.086 ns 9.43 1352 B
Multiple · AsyncLock · NonKeyed 10 None 3,455.383 ns 10.31 2296 B
Multiple · AsyncLock · ProtoPromise 10 NotCancelled 496.349 ns 0.80 -
Multiple · AsyncLock · Pooled (ValueTask) 10 NotCancelled 623.256 ns 1.00 -
Multiple · AsyncLock · NeoSmart 10 NotCancelled 642.343 ns 1.03 2288 B
Multiple · AsyncSemaphore · VS.Threading 10 NotCancelled 734.316 ns 1.18 1680 B
Multiple · AsyncLock · Nito 10 NotCancelled 3,224.239 ns 5.17 6800 B
Multiple · AsyncLock · Pooled (Task) 10 NotCancelled 3,366.491 ns 5.40 1352 B
Multiple · SemaphoreSlim · System 10 NotCancelled 4,357.466 ns 6.99 3888 B
Multiple · AsyncLock · NonKeyed 10 NotCancelled 5,054.288 ns 8.11 5176 B
Multiple · SemaphoreSlim · System 100 None 2,538.924 ns 0.80 8800 B
Multiple · AsyncLock · ProtoPromise 100 None 2,616.672 ns 0.82 -
Multiple · AsyncLock · Pooled (ValueTask) 100 None 3,179.786 ns 1.00 -
Multiple · AsyncSemaphore · VS.Threading 100 None 4,894.898 ns 1.54 21120 B
Multiple · AsyncLock · Nito 100 None 5,325.309 ns 1.67 41120 B
Multiple · AsyncLock · NeoSmart 100 None 5,895.268 ns 1.85 21008 B
Multiple · AsyncLock · RefImpl 100 None 6,318.729 ns 1.99 21600 B
Multiple · AsyncLock · Pooled (Task) 100 None 33,600.780 ns 10.57 12216 B
Multiple · AsyncLock · NonKeyed 100 None 35,603.366 ns 11.20 21800 B
Multiple · AsyncLock · ProtoPromise 100 NotCancelled 4,689.983 ns 0.87 -
Multiple · AsyncLock · Pooled (ValueTask) 100 NotCancelled 5,360.730 ns 1.00 -
Multiple · AsyncLock · NeoSmart 100 NotCancelled 5,968.076 ns 1.11 21008 B
Multiple · AsyncSemaphore · VS.Threading 100 NotCancelled 7,014.726 ns 1.31 21120 B
Multiple · AsyncLock · Nito 100 NotCancelled 31,183.481 ns 5.82 65120 B
Multiple · AsyncLock · Pooled (Task) 100 NotCancelled 35,534.963 ns 6.63 12216 B
Multiple · SemaphoreSlim · System 100 NotCancelled 44,303.836 ns 8.27 37792 B
Multiple · AsyncLock · NonKeyed 100 NotCancelled 54,064.472 ns 10.09 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.5506 ns 0.73 -
Set · AsyncAutoReset · Pooled 0.7530 ns 1.00 -
Set · AsyncAutoReset · Nito.AsyncEx 4.4771 ns 5.95 -
Set · AsyncAutoReset · RefImpl 4.5253 ns 6.02 -
Set · AutoResetEvent · System 215.6038 ns 286.67 -

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.450 ns 0.90 -
SetThenWait · AsyncAutoReset · Pooled (ValueTask) 6.083 ns 1.00 -
SetThenWait · AsyncAutoReset · Pooled (AsTask) 8.694 ns 1.43 -
SetThenWait · AsyncAutoReset · Nito.AsyncEx 14.165 ns 2.33 -
SetThenWait · AsyncAutoReset · RefImpl 15.447 ns 2.54 -

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.66 ns 0.83 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 1 None 25.86 ns 0.90 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 1 None 26.07 ns 0.91 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 1 None 28.53 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 1 None 28.63 ns 1.00 -
WaitThenSet · AsyncAutoReset · RefImpl 1 None 29.02 ns 1.01 96 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 1 None 35.46 ns 1.24 160 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 1 None 42.84 ns 1.50 80 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 1 None 449.80 ns 15.71 231 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 1 NotCancelled 43.33 ns 0.99 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 1 NotCancelled 43.54 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 1 NotCancelled 43.71 ns 1.00 -
WaitThenSet · AsyncAutoReset · ProtoPromise 1 NotCancelled 46.97 ns 1.07 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 1 NotCancelled 66.61 ns 1.52 80 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 1 NotCancelled 77.09 ns 1.76 -
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 1 NotCancelled 337.09 ns 7.71 400 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 1 NotCancelled 514.33 ns 11.77 232 B
WaitThenSet · AsyncAutoReset · ProtoPromise 2 None 46.85 ns 0.66 -
WaitThenSet · AsyncAutoReset · RefImpl 2 None 52.64 ns 0.74 192 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 2 None 63.24 ns 0.89 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 2 None 66.85 ns 0.94 -
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 2 None 67.80 ns 0.95 320 B
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 2 None 71.21 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 2 None 72.04 ns 1.01 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 2 None 101.12 ns 1.42 160 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 2 None 745.18 ns 10.47 343 B
WaitThenSet · AsyncAutoReset · ProtoPromise 2 NotCancelled 91.95 ns 0.90 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 2 NotCancelled 102.11 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 2 NotCancelled 102.94 ns 1.01 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 2 NotCancelled 104.05 ns 1.02 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 2 NotCancelled 106.53 ns 1.04 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 2 NotCancelled 146.62 ns 1.44 160 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 2 NotCancelled 575.66 ns 5.64 800 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 2 NotCancelled 903.74 ns 8.85 344 B
WaitThenSet · AsyncAutoReset · ProtoPromise 10 None 245.19 ns 0.69 -
WaitThenSet · AsyncAutoReset · RefImpl 10 None 281.16 ns 0.79 960 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 10 None 340.86 ns 0.96 -
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 10 None 349.20 ns 0.98 1600 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 10 None 349.23 ns 0.98 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 10 None 356.04 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 10 None 372.92 ns 1.05 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 10 None 533.28 ns 1.50 800 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 10 None 2,115.63 ns 5.94 1237 B
WaitThenSet · AsyncAutoReset · ProtoPromise 10 NotCancelled 458.40 ns 0.83 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 10 NotCancelled 535.05 ns 0.96 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 10 NotCancelled 545.01 ns 0.98 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 10 NotCancelled 549.83 ns 0.99 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 10 NotCancelled 554.84 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 10 NotCancelled 768.56 ns 1.39 800 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 10 NotCancelled 2,908.98 ns 5.24 4000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 10 NotCancelled 3,374.46 ns 6.08 1239 B
WaitThenSet · AsyncAutoReset · ProtoPromise 100 None 2,267.45 ns 0.65 -
WaitThenSet · AsyncAutoReset · RefImpl 100 None 2,767.11 ns 0.79 9600 B
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 100 None 3,149.15 ns 0.90 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 100 None 3,185.54 ns 0.91 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 100 None 3,508.92 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 100 None 3,532.61 ns 1.01 -
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 100 None 3,555.60 ns 1.01 16000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 100 None 5,238.56 ns 1.49 8000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 100 None 16,210.37 ns 4.62 11320 B
WaitThenSet · AsyncAutoReset · ProtoPromise 100 NotCancelled 4,746.20 ns 0.90 -
WaitThenSet · AsyncAutoReset · Pooled (ValueTask) 100 NotCancelled 5,263.17 ns 1.00 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask) 100 NotCancelled 5,327.80 ns 1.01 -
WaitThenSet · AsyncAutoReset · Pooled (SyncCont) 100 NotCancelled 5,349.26 ns 1.02 -
WaitThenSet · AsyncAutoReset · Pooled (AsValueTask SyncCont) 100 NotCancelled 5,645.75 ns 1.07 -
WaitThenSet · AsyncAutoReset · Pooled (AsTask SyncCont) 100 NotCancelled 7,803.78 ns 1.48 8000 B
WaitThenSet · AsyncAutoReset · Nito.AsyncEx 100 NotCancelled 28,920.30 ns 5.50 40000 B
WaitThenSet · AsyncAutoReset · Pooled (AsTask) 100 NotCancelled 290,521.43 ns 55.20 11324 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.447 ns 0.71 -
SetReset · AsyncManualReset · Pooled 2.050 ns 1.00 -
SetReset · ManualResetEventSlim · System 5.438 ns 2.65 -
SetReset · AsyncManualReset · RefImpl 9.979 ns 4.87 96 B
SetReset · AsyncManualReset · Nito.AsyncEx 17.013 ns 8.30 96 B
SetReset · ManualResetEvent · System 432.047 ns 210.74 -

SetThenWait

Description Mean Ratio Allocated
SetThenWait · AsyncManualReset · ProtoPromise 5.864 ns 0.64 -
SetThenWait · AsyncManualReset · Pooled (ValueTask) 9.203 ns 1.00 -
SetThenWait · AsyncManualReset · Pooled (AsTask) 9.251 ns 1.01 -
SetThenWait · AsyncManualReset · RefImpl 13.676 ns 1.49 96 B
SetThenWait · AsyncManualReset · Nito.AsyncEx 24.142 ns 2.62 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.31 ns 0.73 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 1 None 26.05 ns 0.90 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 1 None 26.90 ns 0.93 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 1 None 27.19 ns 0.94 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 1 None 28.86 ns 0.99 -
WaitThenSet · AsyncManualReset · Nito.AsyncEx 1 None 29.00 ns 1.00 96 B
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 1 None 29.01 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 1 None 41.05 ns 1.42 80 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 1 None 439.28 ns 15.14 231 B
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 1 NotCancelled 43.70 ns 0.96 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 1 NotCancelled 44.63 ns 0.98 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 1 NotCancelled 45.36 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 1 NotCancelled 45.72 ns 1.01 -
WaitThenSet · AsyncManualReset · ProtoPromise 1 NotCancelled 47.92 ns 1.06 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 1 NotCancelled 63.31 ns 1.40 80 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 1 NotCancelled 487.66 ns 10.75 232 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 1 NotCancelled 619.69 ns 13.66 808 B
WaitThenSet · AsyncManualReset · RefImpl 2 None 24.12 ns 0.37 96 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 2 None 38.01 ns 0.58 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 2 None 45.85 ns 0.70 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 2 None 59.82 ns 0.92 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 2 None 60.29 ns 0.92 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 2 None 65.21 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 2 None 65.37 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 2 None 91.73 ns 1.40 160 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 2 None 769.23 ns 11.77 344 B
WaitThenSet · AsyncManualReset · ProtoPromise 2 NotCancelled 89.35 ns 0.88 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 2 NotCancelled 93.97 ns 0.92 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 2 NotCancelled 99.86 ns 0.98 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 2 NotCancelled 101.01 ns 0.99 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 2 NotCancelled 101.79 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 2 NotCancelled 140.33 ns 1.38 160 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 2 NotCancelled 900.51 ns 8.85 344 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 2 NotCancelled 1,075.26 ns 10.56 1488 B
WaitThenSet · AsyncManualReset · RefImpl 10 None 65.32 ns 0.18 96 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 10 None 111.64 ns 0.31 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 10 None 213.75 ns 0.60 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 10 None 319.12 ns 0.90 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 10 None 322.67 ns 0.91 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 10 None 351.34 ns 0.99 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 10 None 354.82 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 10 None 486.56 ns 1.37 800 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 10 None 2,053.86 ns 5.79 1239 B
WaitThenSet · AsyncManualReset · ProtoPromise 10 NotCancelled 426.86 ns 0.81 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 10 NotCancelled 518.51 ns 0.98 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 10 NotCancelled 527.70 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 10 NotCancelled 531.19 ns 1.01 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 10 NotCancelled 552.29 ns 1.05 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 10 NotCancelled 725.76 ns 1.38 800 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 10 NotCancelled 2,835.69 ns 5.37 1240 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 10 NotCancelled 3,459.05 ns 6.56 6464 B
WaitThenSet · AsyncManualReset · RefImpl 100 None 545.01 ns 0.16 96 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 100 None 929.35 ns 0.27 96 B
WaitThenSet · AsyncManualReset · ProtoPromise 100 None 2,117.15 ns 0.62 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 100 None 3,064.17 ns 0.89 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 100 None 3,078.54 ns 0.90 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 100 None 3,435.63 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 100 None 3,459.37 ns 1.01 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 100 None 4,804.34 ns 1.40 8000 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 100 None 15,421.83 ns 4.49 11320 B
WaitThenSet · AsyncManualReset · ProtoPromise 100 NotCancelled 4,210.12 ns 0.81 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask) 100 NotCancelled 5,195.50 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (ValueTask) 100 NotCancelled 5,212.95 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (AsValueTask SyncCont) 100 NotCancelled 5,218.04 ns 1.00 -
WaitThenSet · AsyncManualReset · Pooled (SyncCont) 100 NotCancelled 5,247.35 ns 1.01 -
WaitThenSet · AsyncManualReset · Pooled (AsTask SyncCont) 100 NotCancelled 7,302.66 ns 1.40 8000 B
WaitThenSet · AsyncManualReset · Nito.AsyncEx 100 NotCancelled 128,084.00 ns 24.57 61615 B
WaitThenSet · AsyncManualReset · Pooled (AsTask) 100 NotCancelled 309,059.35 ns 59.29 11326 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.398 ns 0.70 -
WaitRelease · AsyncSemaphore · Pooled 9.083 ns 1.00 -
WaitRelease · AsyncSemaphore · Nito.AsyncEx 14.655 ns 1.61 -
WaitRelease · SemaphoreSlim · System 16.827 ns 1.85 -
WaitRelease · AsyncSemaphore · RefImpl 17.893 ns 1.97 -

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.767 ns 0.89 -
SignalAndWait · AsyncCountdownEv · Pooled 1 7.574 ns 1.00 -
SignalAndWait · AsyncCountdownEv · ProtoPromise 1 7.588 ns 1.00 -
SignalAndWait · AsyncCountdownEv · RefImpl 1 16.461 ns 2.17 96 B
WaitAndSignal · AsyncCountdownEv · ProtoPromise 1 18.802 ns 2.48 -
WaitAndSignal · AsyncCountdownEv · Pooled 1 49.150 ns 6.49 -
SignalAndWait · AsyncCountdownEv · ProtoPromise 10 17.544 ns 0.76 -
SignalAndWait · CountdownEvent · System 10 20.060 ns 0.87 -
SignalAndWait · AsyncCountdownEv · Pooled 10 23.027 ns 1.00 -
SignalAndWait · AsyncCountdownEv · RefImpl 10 28.830 ns 1.25 96 B
WaitAndSignal · AsyncCountdownEv · ProtoPromise 10 29.128 ns 1.26 -
WaitAndSignal · AsyncCountdownEv · Pooled 10 64.808 ns 2.81 -

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 11.34 ns 1.00 -
SignalAndWait · Barrier · System 1 440.59 ns 38.86 238 B
SignalAndWait · AsyncBarrier · RefImpl 1 966.04 ns 85.21 8356 B
SignalAndWait · AsyncBarrier · Pooled 10 268.81 ns 1.00 -
SignalAndWait · AsyncBarrier · RefImpl 10 1,598.64 ns 5.95 10032 B
SignalAndWait · Barrier · System 10 4,645.62 ns 17.28 1392 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.931 ns 0.62 -
WriterLock · AsyncRWLock · Proto.Promises 8.353 ns 0.75 -
WriterLock · AsyncRWLock · Pooled 11.103 ns 1.00 -
WriterLock · AsyncRWLock · RefImpl 18.529 ns 1.67 -
WriterLock · AsyncRWLock · Nito.AsyncEx 55.739 ns 5.02 496 B
WriterLock · AsyncRWLock · VS.Threading 1,044.066 ns 94.04 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 7.728 ns 0.49 -
ReaderLock · AsyncRWLock · Pooled 0 None 15.803 ns 1.00 -
ReaderLock · AsyncRWLock · Proto.Promises 0 None 18.267 ns 1.16 -
ReaderLock · AsyncRWLock · RefImpl 0 None 18.839 ns 1.19 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 0 None 40.865 ns 2.59 320 B
ReaderLock · AsyncRWLock · VS.Threading 0 None 224.367 ns 14.20 208 B
ReaderLock · AsyncRWLock · Pooled 0 NotCancelled 15.951 ns 1.00 -
ReaderLock · AsyncRWLock · Proto.Promises 0 NotCancelled 18.197 ns 1.14 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 0 NotCancelled 40.386 ns 2.53 320 B
ReaderLock · AsyncRWLock · VS.Threading 0 NotCancelled 225.331 ns 14.13 208 B
ReaderLock · RWLockSlim · System 1 None 12.326 ns 0.30 -
ReaderLock · AsyncRWLock · Proto.Promises 1 None 28.524 ns 0.69 -
ReaderLock · AsyncRWLock · RefImpl 1 None 33.435 ns 0.80 -
ReaderLock · AsyncRWLock · Pooled 1 None 41.565 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 1 None 83.736 ns 2.01 640 B
ReaderLock · AsyncRWLock · VS.Threading 1 None 531.027 ns 12.78 416 B
ReaderLock · AsyncRWLock · Proto.Promises 1 NotCancelled 28.778 ns 0.71 -
ReaderLock · AsyncRWLock · Pooled 1 NotCancelled 40.399 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 1 NotCancelled 81.648 ns 2.02 640 B
ReaderLock · AsyncRWLock · VS.Threading 1 NotCancelled 532.178 ns 13.17 416 B
ReaderLock · RWLockSlim · System 10 None 61.963 ns 0.32 -
ReaderLock · AsyncRWLock · Proto.Promises 10 None 141.332 ns 0.73 -
ReaderLock · AsyncRWLock · RefImpl 10 None 143.397 ns 0.74 -
ReaderLock · AsyncRWLock · Pooled 10 None 194.403 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 10 None 467.103 ns 2.40 3520 B
ReaderLock · AsyncRWLock · VS.Threading 10 None 3,642.898 ns 18.74 2288 B
ReaderLock · AsyncRWLock · Proto.Promises 10 NotCancelled 139.359 ns 0.72 -
ReaderLock · AsyncRWLock · Pooled 10 NotCancelled 194.276 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 10 NotCancelled 464.283 ns 2.39 3520 B
ReaderLock · AsyncRWLock · VS.Threading 10 NotCancelled 3,640.725 ns 18.74 2288 B
ReaderLock · RWLockSlim · System 100 None 570.326 ns 0.33 -
ReaderLock · AsyncRWLock · Proto.Promises 100 None 1,223.857 ns 0.70 -
ReaderLock · AsyncRWLock · RefImpl 100 None 1,249.889 ns 0.71 -
ReaderLock · AsyncRWLock · Pooled 100 None 1,748.960 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 100 None 4,435.991 ns 2.54 32320 B
ReaderLock · AsyncRWLock · VS.Threading 100 None 86,096.879 ns 49.23 21008 B
ReaderLock · AsyncRWLock · Proto.Promises 100 NotCancelled 1,245.661 ns 0.71 -
ReaderLock · AsyncRWLock · Pooled 100 NotCancelled 1,743.212 ns 1.00 -
ReaderLock · AsyncRWLock · Nito.AsyncEx 100 NotCancelled 4,404.138 ns 2.53 32320 B
ReaderLock · AsyncRWLock · VS.Threading 100 NotCancelled 87,835.002 ns 50.39 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.741 ns 0.41 -
UpgradeableReaderLock · AsyncRWLock · Pooled 0 None 16.248 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 0 None 19.423 ns 1.20 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 0 None 1,064.281 ns 65.50 616 B
UpgradeableReaderLock · AsyncRWLock · Pooled 0 NotCancelled 16.334 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 0 NotCancelled 17.778 ns 1.09 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 0 NotCancelled 1,135.176 ns 69.50 616 B
UpgradeableReaderLock · RWLockSlim · System 1 None 6.725 ns 0.34 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 1 None 17.560 ns 0.90 -
UpgradeableReaderLock · AsyncRWLock · Pooled 1 None 19.551 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 1 None 1,048.830 ns 53.65 616 B
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 1 NotCancelled 17.601 ns 0.92 -
UpgradeableReaderLock · AsyncRWLock · Pooled 1 NotCancelled 19.051 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 1 NotCancelled 1,181.340 ns 62.01 616 B
UpgradeableReaderLock · RWLockSlim · System 2 None 6.733 ns 0.36 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 2 None 17.646 ns 0.94 -
UpgradeableReaderLock · AsyncRWLock · Pooled 2 None 18.809 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 2 None 1,045.428 ns 55.58 616 B
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 2 NotCancelled 17.493 ns 0.90 -
UpgradeableReaderLock · AsyncRWLock · Pooled 2 NotCancelled 19.365 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 2 NotCancelled 1,179.300 ns 60.90 616 B
UpgradeableReaderLock · RWLockSlim · System 5 None 24.080 ns 0.31 -
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 5 None 52.959 ns 0.69 -
UpgradeableReaderLock · AsyncRWLock · Pooled 5 None 76.546 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 5 None 2,477.664 ns 32.37 1240 B
UpgradeableReaderLock · AsyncRWLock · Proto.Promises 5 NotCancelled 53.909 ns 0.72 -
UpgradeableReaderLock · AsyncRWLock · Pooled 5 NotCancelled 74.742 ns 1.00 -
UpgradeableReaderLock · AsyncRWLock · VS.Threading 5 NotCancelled 2,586.760 ns 34.61 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.49 ns 0.53 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 0 None 23.76 ns 0.93 -
UpgradedWriterLock · AsyncRWLock · Pooled 0 None 25.64 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 0 None 1,716.69 ns 66.97 824 B
UpgradedWriterLock · AsyncRWLock · Proto.Promises 0 NotCancelled 24.74 ns 0.97 -
UpgradedWriterLock · AsyncRWLock · Pooled 0 NotCancelled 25.37 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 0 NotCancelled 1,785.84 ns 70.39 824 B
UpgradedWriterLock · RWLockSlim · System 1 None 34.65 ns 0.63 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 1 None 44.20 ns 0.81 -
UpgradedWriterLock · AsyncRWLock · Pooled 1 None 54.81 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 1 None 2,233.12 ns 40.74 1032 B
UpgradedWriterLock · AsyncRWLock · Pooled 1 NotCancelled 65.71 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 1 NotCancelled 69.90 ns 1.06 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 1 NotCancelled 2,269.89 ns 34.55 1032 B
UpgradedWriterLock · RWLockSlim · System 2 None 25.47 ns 0.33 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 2 None 53.43 ns 0.69 -
UpgradedWriterLock · AsyncRWLock · Pooled 2 None 77.54 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 2 None 2,717.26 ns 35.04 1240 B
UpgradedWriterLock · AsyncRWLock · Proto.Promises 2 NotCancelled 80.98 ns 0.86 -
UpgradedWriterLock · AsyncRWLock · Pooled 2 NotCancelled 94.63 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 2 NotCancelled 2,780.83 ns 29.39 1240 B
UpgradedWriterLock · RWLockSlim · System 5 None 43.55 ns 0.31 -
UpgradedWriterLock · AsyncRWLock · Proto.Promises 5 None 91.85 ns 0.66 -
UpgradedWriterLock · AsyncRWLock · Pooled 5 None 139.13 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 5 None 4,235.82 ns 30.45 1864 B
UpgradedWriterLock · AsyncRWLock · Proto.Promises 5 NotCancelled 116.29 ns 0.80 -
UpgradedWriterLock · AsyncRWLock · Pooled 5 NotCancelled 146.08 ns 1.00 -
UpgradedWriterLock · AsyncRWLock · VS.Threading 5 NotCancelled 4,381.78 ns 30.00 1864 B