|
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Threading; |
|
using BenchmarkDotNet.Attributes; |
|
using BenchmarkDotNet.Configs; |
|
|
|
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] |
|
[CategoriesColumn] |
|
[MemoryDiagnoser] |
|
public class Tests { |
|
// No Args |
|
static readonly object[] NoArgs = Array.Empty<object>(); |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(NoArgs))] |
|
public (Dictionary<string, object>, List<string>) Original_NoArgs() { |
|
return Test(NoArgs, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(NoArgs))] |
|
public (Dictionary<string, object>, List<string>) Update_NoArgs() { |
|
return Test(NoArgs, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(NoArgs))] |
|
public (Dictionary<string, object>, List<string>) With256_NoArgs() { |
|
return Test(NoArgs, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(NoArgs))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_NoArgs() { |
|
return Test(NoArgs, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// One Arg No Streaming |
|
static readonly object[] OneArg_NoStreaming = new [] { new object() }; |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(OneArg_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_OneArg_NoStreaming() { |
|
return Test(OneArg_NoStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(OneArg_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_OneArg_NoStreaming() { |
|
return Test(OneArg_NoStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(OneArg_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_OneArg_NoStreaming() { |
|
return Test(OneArg_NoStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(OneArg_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_OneArg_NoStreaming() { |
|
return Test(OneArg_NoStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// One Arg One Streaming |
|
static readonly object[] OneArg_OneStreaming = new [] { new MockAsyncEnumerable<int>() }; |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(OneArg_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_OneArg_OneStreaming() { |
|
return Test(OneArg_OneStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(OneArg_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_OneArg_OneStreaming() { |
|
return Test(OneArg_OneStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(OneArg_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_OneArg_OneStreaming() { |
|
return Test(OneArg_OneStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(OneArg_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_OneArg_OneStreaming() { |
|
return Test(OneArg_OneStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Two Args No Streaming |
|
static readonly object[] TwoArgs_NoStreaming = new [] { new object(), new object() }; |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(TwoArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_TwoArgs_NoStreaming() { |
|
return Test(TwoArgs_NoStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TwoArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_TwoArgs_NoStreaming() { |
|
return Test(TwoArgs_NoStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TwoArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_TwoArgs_NoStreaming() { |
|
return Test(TwoArgs_NoStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TwoArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_TwoArgs_NoStreaming() { |
|
return Test(TwoArgs_NoStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Two Args One Streaming |
|
static readonly object[] TwoArgs_OneStreaming = new [] { new object(), new MockAsyncEnumerable<int>() }; |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(TwoArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_TwoArgs_OneStreaming() { |
|
return Test(TwoArgs_OneStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TwoArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_TwoArgs_OneStreaming() { |
|
return Test(TwoArgs_OneStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TwoArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_TwoArgs_OneStreaming() { |
|
return Test(TwoArgs_OneStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TwoArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_TwoArgs_OneStreaming() { |
|
return Test(TwoArgs_OneStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Ten Args No Streaming |
|
static readonly object[] TenArgs_NoStreaming = Enumerable.Repeat(new object(), 10).ToArray(); |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(TenArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_TenArgs_NoStreaming() { |
|
return Test(TenArgs_NoStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TenArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_TenArgs_NoStreaming() { |
|
return Test(TenArgs_NoStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TenArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_TenArgs_NoStreaming() { |
|
return Test(TenArgs_NoStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TenArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_TenArgs_NoStreaming() { |
|
return Test(TenArgs_NoStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Ten Args One Streaming |
|
static readonly object[] TenArgs_OneStreaming = Enumerable.Repeat(new object(), 5) |
|
.Append(new MockAsyncEnumerable<int>()) |
|
.Concat(Enumerable.Repeat(new object(), 4)) |
|
.ToArray(); |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(TenArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_TenArgs_OneStreaming() { |
|
return Test(TenArgs_OneStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TenArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_TenArgs_OneStreaming() { |
|
return Test(TenArgs_OneStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TenArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_TenArgs_OneStreaming() { |
|
return Test(TenArgs_OneStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(TenArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_TenArgs_OneStreaming() { |
|
return Test(TenArgs_OneStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Many Args No Streaming |
|
static readonly object[] ManyArgs_NoStreaming = Enumerable.Repeat(new object(), 1024) |
|
.ToArray(); |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(ManyArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_ManyArgs_NoStreaming() { |
|
return Test(ManyArgs_NoStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_ManyArgs_NoStreaming() { |
|
return Test(ManyArgs_NoStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_ManyArgs_NoStreaming() { |
|
return Test(ManyArgs_NoStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_NoStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_ManyArgs_NoStreaming() { |
|
return Test(ManyArgs_NoStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Many Args One Streaming |
|
static readonly object[] ManyArgs_OneStreaming = Enumerable.Repeat(new object(), 512) |
|
.Append(new MockAsyncEnumerable<int>()) |
|
.Concat(Enumerable.Repeat(new object(), 511)) |
|
.ToArray(); |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(ManyArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_ManyArgs_OneStreaming() { |
|
return Test(ManyArgs_OneStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_ManyArgs_OneStreaming() { |
|
return Test(ManyArgs_OneStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_ManyArgs_OneStreaming() { |
|
return Test(ManyArgs_OneStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_OneStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_ManyArgs_OneStreaming() { |
|
return Test(ManyArgs_OneStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Many Args All Streaming |
|
static readonly object[] ManyArgs_AllStreaming = Enumerable.Repeat( |
|
new MockAsyncEnumerable<int>(), 1024 |
|
).ToArray(); |
|
[Benchmark(Baseline = true)] |
|
[BenchmarkCategory(nameof(ManyArgs_AllStreaming))] |
|
public (Dictionary<string, object>, List<string>) Original_ManyArgs_AllStreaming() { |
|
return Test(ManyArgs_AllStreaming, Original.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_AllStreaming))] |
|
public (Dictionary<string, object>, List<string>) Update_ManyArgs_AllStreaming() { |
|
return Test(ManyArgs_AllStreaming, Update.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_AllStreaming))] |
|
public (Dictionary<string, object>, List<string>) With256_ManyArgs_AllStreaming() { |
|
return Test(ManyArgs_AllStreaming, With256.PackageStreamingParams); |
|
} |
|
[Benchmark] |
|
[BenchmarkCategory(nameof(ManyArgs_AllStreaming))] |
|
public (Dictionary<string, object>, List<string>) WithSkipLocalsInit_ManyArgs_AllStreaming() { |
|
return Test(ManyArgs_AllStreaming, WithSkipLocalsInit.PackageStreamingParams); |
|
} |
|
|
|
// Helpers |
|
ConnectionState _connectionState; |
|
[GlobalSetup] |
|
public void GlobalSetup() { |
|
_connectionState = new ConnectionState(); |
|
} |
|
delegate Dictionary<string, object> Packager(ConnectionState connectionState, ref object[] args, out List<string> streamIds); |
|
|
|
(Dictionary<string, object>, List<string>) Test(object[] args, Packager packager) { |
|
var readers = packager( |
|
_connectionState, ref args, out var streamIds |
|
); |
|
|
|
return (readers, streamIds); |
|
} |
|
|
|
class MockAsyncEnumerable<T> : IAsyncEnumerable<T> |
|
{ |
|
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
} |
|
} |