Skip to content

Benchmark Tests

Damian edited this page Jan 10, 2026 · 6 revisions

The following is a collection of Benchmark Tests to showcase release iterations.

  • Executes both sync and async
  • Transition Cycles: 1, 100, 1_000, 10_000
    • State1 -> State2 -> State3 -> [State1 -> ...]
  • Sample alternate configuration
BenchmarkDotNet v0.15.8, Windows 11 (10.0.22631.6345/23H2/2023Update/SunValley3)
13th Gen Intel Core i9-13950HX 2.20GHz, 1 CPU, 32 logical and 24 physical cores
.NET SDK 10.0.101
  [Host]     : .NET 10.0.1 (10.0.1, 10.0.125.57005), X64 RyuJIT x86-64-v3
  DefaultJob : .NET 10.0.1 (10.0.1, 10.0.125.57005), X64 RyuJIT x86-64-v3

Legends:
  CyclesBeforeExit : Value of the 'CyclesBeforeExit' parameter
  Mean             : Arithmetic mean of all measurements
  Error            : Half of 99.9% confidence interval
  StdDev           : Standard deviation of all measurements
  Median           : Value separating the higher half of all measurements (50th percentile)
  Gen0             : GC Generation 0 collects per 1000 operations
  Allocated        : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
  1 ns             : 1 Nanosecond (0.000000001 sec)

v2.2.x

v2.2.1

Date: 2026-01-04

| Method               | CyclesBeforeExit | Mean     | Error    | StdDev   | Gen0   | Allocated |
|----------------------|----------------- |---------:|---------:|---------:|-------:|----------:|
| BasicStatesRunsAsync | 1                | 705.4 ns | 14.01 ns | 31.35 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsSync  | 1                | 702.7 ns |  9.56 ns |  8.47 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsAsync | 100              | 699.1 ns | 11.94 ns |  9.32 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsSync  | 100              | 686.1 ns | 13.56 ns | 16.66 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsAsync | 1000             | 688.5 ns |  6.22 ns |  5.20 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsSync  | 1000             | 667.7 ns |  6.12 ns |  5.73 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsAsync | 10000            | 694.7 ns |  3.33 ns |  2.78 ns | 0.1965 |   3.62 KB |
| BasicStatesRunsSync  | 10000            | 679.2 ns | 11.24 ns |  8.78 ns | 0.1965 |   3.62 KB |

v2.2.0-alpha1

Date: 2026-01-03

| Method               | CyclesBeforeExit | Mean     | Error    | StdDev   | Gen0   | Allocated |
|----------------------|----------------- |---------:|---------:|---------:|-------:|----------:|
| BasicStatesRunsAsync | 1                | 999.9 ns | 19.26 ns | 18.91 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsSync  | 1                | 977.8 ns | 19.57 ns | 47.25 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsAsync | 100              | 738.8 ns | 14.81 ns | 32.20 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsSync  | 100              | 691.0 ns | 11.56 ns | 10.81 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsAsync | 1000             | 702.0 ns |  7.57 ns |  6.71 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsSync  | 1000             | 664.2 ns |  6.05 ns |  5.66 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsAsync | 10000            | 713.4 ns | 14.23 ns | 18.50 ns | 0.1926 |   3.55 KB |
| BasicStatesRunsSync  | 10000            | 718.9 ns | 13.45 ns | 26.24 ns | 0.1926 |   3.55 KB |

Pre-Releases

v2.3.0-Alpha2

  • Date: 2026-01-10 - Improve Context
  • Story: #88
| Method               | CyclesBeforeExit | Mean     | Error    | StdDev   | Gen0   | Allocated |
|--------------------- |----------------- |---------:|---------:|---------:|-------:|----------:|
| BasicStatesRunsAsync | 1                | 611.5 ns |  2.75 ns |  2.57 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsSync  | 1                | 608.8 ns |  5.26 ns |  4.66 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsAsync | 100              | 613.9 ns |  3.59 ns |  3.35 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsSync  | 100              | 609.2 ns |  3.58 ns |  3.17 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsAsync | 1000             | 613.9 ns |  5.39 ns |  4.78 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsSync  | 1000             | 606.4 ns |  5.32 ns |  4.71 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsAsync | 10000            | 613.7 ns |  8.11 ns |  7.58 ns | 0.1526 |   2.81 KB |
| BasicStatesRunsSync  | 10000            | 616.9 ns | 11.39 ns | 10.65 ns | 0.1526 |   2.81 KB |

v2.3.0-Alpha1

Date: 2026-01-10

| Method               | CyclesBeforeExit | Mean     | Error   | StdDev  | Gen0   | Allocated |
|--------------------- |----------------- |---------:|--------:|--------:|-------:|----------:|
| BasicStatesRunsAsync | 1                | 680.2 ns | 6.87 ns | 6.43 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 1                | 664.9 ns | 2.76 ns | 2.58 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsAsync | 100              | 672.6 ns | 6.35 ns | 5.63 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 100              | 652.7 ns | 4.04 ns | 3.38 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsAsync | 1000             | 667.9 ns | 9.63 ns | 8.53 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 1000             | 662.1 ns | 6.22 ns | 5.51 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsAsync | 10000            | 669.8 ns | 6.42 ns | 6.00 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 10000            | 662.6 ns | 4.22 ns | 3.74 ns | 0.1974 |   3.64 KB |

Date: 2026-01-09

| Method               | CyclesBeforeExit | Mean     | Error    | StdDev   | Gen0   | Allocated |
|--------------------- |----------------- |---------:|---------:|---------:|-------:|----------:|
| BasicStatesRunsAsync | 1                | 743.3 ns | 13.46 ns | 11.93 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 1                | 709.5 ns | 12.86 ns | 13.76 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsAsync | 100              | 701.1 ns | 13.52 ns | 12.65 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 100              | 710.0 ns | 12.20 ns | 11.41 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsAsync | 1000             | 718.8 ns |  5.97 ns |  4.66 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 1000             | 704.2 ns | 10.97 ns | 10.26 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsAsync | 10000            | 726.3 ns | 14.33 ns | 15.33 ns | 0.1974 |   3.64 KB |
| BasicStatesRunsSync  | 10000            | 725.5 ns | 11.70 ns | 10.37 ns | 0.1974 |   3.64 KB |

Benchmark Classes

Tests

  [GlobalSetup]
  public void BasicStateGlobalSetup()
  {
    _machine = new StateMachine<BasicStateId>(null, null, isContextPersistent: true);
    _machine.RegisterState<BasicState1>(BasicStateId.State1, BasicStateId.State2);
    _machine.RegisterState<BasicState2>(BasicStateId.State2, BasicStateId.State3);
    _machine.RegisterState<BasicState3>(BasicStateId.State3, onSuccess: null, onError: BasicStateId.State1);
  }

  [Benchmark]
  public async Task BasicStatesRunsAsync()
  {
    var maxCounter = CyclesBeforeExit;
    PropertyBag parameters = new() { { ParameterType.MaxCounter, maxCounter }, { ParameterType.Counter, 0 } };
    await _machine.RunAsync(BasicStateId.State1, parameters);
  }

State Classes

public class BasicState1 : StateBase<BasicState1, BasicStateId>;

public class BasicState2 : StateBase<BasicState2, BasicStateId>;

public class BasicState3 : StateBase<BasicState3, BasicStateId>
{
  public override Task OnEnter(Context<BasicStateId> context)
  {
    var max = context.ParameterAsInt(ParameterType.MaxCounter);
    var cnt = context.ParameterAsInt(ParameterType.Counter);
    cnt++;
    context.Parameters.SafeAdd(ParameterType.Counter, cnt);

    if (cnt > max)
      context.NextState(Result.Success);
    else
      context.NextState(Result.Error);

    return Task.CompletedTask;
  }
}

Clone this wiki locally