[LOADED_DOCS: 2 files, no new loads]
Refactor benchmarks to use typed enums for engine/mode Replaced string-based identifiers for serializer engine, I/O mode, and dispatch mode with strongly-typed enums (BenchmarkEngine, BenchmarkIoMode, BenchmarkDispatchMode). Added BenchmarkEnums.cs with ToDisplay() helpers for consistent output. Updated all benchmark implementations, DTOs, and output logic to use enums. Removed obsolete string constants from Configuration.cs. Merged allocation measurement methods in BenchmarkLoop.cs for clarity. Improves type safety, maintainability, and output consistency.
This commit is contained in:
parent
ad9e05413c
commit
eaafb00739
|
|
@ -227,7 +227,7 @@ internal static class BenchmarkLoop
|
|||
result.RoundTripIterations = rtIter;
|
||||
// Process-wide allocation measurement: server-drain-thread allocations (server-side new byte[len])
|
||||
// also show up — otherwise current-thread alloc would only count the client side and look ~halved.
|
||||
result.RoundTripAllocBytesPerOp = MeasureAllocationTotal(() => serializer.Serialize(), rtIter, $"{groupLabel} [RT alloc]");
|
||||
result.RoundTripAllocBytesPerOp = MeasureAllocation(() => serializer.Serialize(), rtIter, $"{groupLabel} [RT alloc]", processWide: true);
|
||||
}
|
||||
// mode == "deserialize" alone is meaningless for a round-trip-only benchmark; skip silently.
|
||||
}
|
||||
|
|
@ -611,43 +611,24 @@ internal static class BenchmarkLoop
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Measures per-call allocation in bytes after a clean GC. Single dedicated sample (no median) — keeps timing samples pure.
|
||||
/// Measures per-call allocation in bytes after a clean GC. Single dedicated sample (no median) — keeps
|
||||
/// timing samples pure. When <paramref name="processWide"/> is <c>true</c>, uses
|
||||
/// <see cref="GC.GetTotalAllocatedBytes"/> instead of <see cref="GC.GetAllocatedBytesForCurrentThread"/>
|
||||
/// — needed for round-trip-only benchmarks (NamedPipe etc.) where the work happens across multiple
|
||||
/// threads (server-side <c>new byte[len]</c> buffers, drain-pump-thread allocations). Per-thread mode
|
||||
/// is slightly cleaner for in-memory benchmarks; process-wide mode is slightly noisier (background
|
||||
/// threads / GC bookkeeping leak in) but over 1000 iterations the signal dominates.
|
||||
/// </summary>
|
||||
internal static long MeasureAllocation(Action action, int iterations, string? progressLabel = null)
|
||||
internal static long MeasureAllocation(Action action, int iterations, string? progressLabel = null, bool processWide = false)
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
var before = GC.GetAllocatedBytesForCurrentThread();
|
||||
var before = processWide ? GC.GetTotalAllocatedBytes(precise: true) : GC.GetAllocatedBytesForCurrentThread();
|
||||
RunWithProgress(action, iterations, progressLabel, samples: 1, sampleIndex: 0);
|
||||
|
||||
var after = GC.GetAllocatedBytesForCurrentThread();
|
||||
sw.Stop();
|
||||
EndProgress(progressLabel, sw.Elapsed.TotalMilliseconds);
|
||||
return (after - before) / iterations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process-wide allocation measurement — needed for round-trip-only benchmarks (NamedPipe etc.) where
|
||||
/// the work happens across multiple threads. <see cref="GC.GetAllocatedBytesForCurrentThread"/> would
|
||||
/// only count the caller-thread allocations, missing the server-side <c>new byte[len]</c> buffers and
|
||||
/// any drain-pump-thread allocations. <see cref="GC.GetTotalAllocatedBytes"/> covers the entire process.
|
||||
/// Slightly noisier than the per-thread variant (background threads / GC bookkeeping leak in), but
|
||||
/// over 1000 iterations the signal dominates.
|
||||
/// </summary>
|
||||
internal static long MeasureAllocationTotal(Action action, int iterations, string? progressLabel = null)
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
var before = GC.GetTotalAllocatedBytes(precise: true);
|
||||
RunWithProgress(action, iterations, progressLabel, samples: 1, sampleIndex: 0);
|
||||
|
||||
var after = GC.GetTotalAllocatedBytes(precise: true);
|
||||
var after = processWide ? GC.GetTotalAllocatedBytes(precise: true) : GC.GetAllocatedBytesForCurrentThread();
|
||||
sw.Stop();
|
||||
EndProgress(progressLabel, sw.Elapsed.TotalMilliseconds);
|
||||
return (after - before) / iterations;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using AyCode.Core.Serializers.Console.Benchmarks;
|
||||
|
||||
namespace AyCode.Core.Serializers.Console;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -8,9 +10,9 @@ namespace AyCode.Core.Serializers.Console;
|
|||
internal sealed class BenchmarkResult
|
||||
{
|
||||
public string TestDataName { get; set; } = "";
|
||||
public string Engine { get; set; } = "";
|
||||
public string IoMode { get; set; } = "";
|
||||
public string DispatchMode { get; set; } = "";
|
||||
public BenchmarkEngine Engine { get; set; }
|
||||
public BenchmarkIoMode IoMode { get; set; }
|
||||
public BenchmarkDispatchMode DispatchMode { get; set; }
|
||||
public string OptionsPreset { get; set; } = "";
|
||||
|
||||
/// <summary>True if Serialize() captures a full round-trip and Deserialize() is a no-op
|
||||
|
|
@ -20,7 +22,7 @@ internal sealed class BenchmarkResult
|
|||
public bool IsRoundTripOnly { get; set; }
|
||||
|
||||
/// <summary>Synthesized display name for backwards compatibility / single-string-row scenarios. Includes DispatchMode so SGen and Runtime variants of the same preset don't collide in grouping (e.g. SUMMARY: WINNERS).</summary>
|
||||
public string SerializerName => $"{Engine} ({IoMode}, {OptionsPreset}, {DispatchMode})";
|
||||
public string SerializerName => $"{Engine.ToDisplay()} ({IoMode.ToDisplay()}, {OptionsPreset}, {DispatchMode.ToDisplay()})";
|
||||
|
||||
public string? OptionsDescription { get; set; }
|
||||
public int SerializedSize { get; set; }
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ internal sealed class AcBinaryBenchmark : ISerializerBenchmark
|
|||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoByteArray;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.ByteArray;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes => 0;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
|
|||
private readonly byte[] _serialized;
|
||||
private readonly ArrayBufferWriter<byte> _bufferWriter;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoBufWrReuse;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.BufWrReuse;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes { get; }
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
|
|||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoBufWrNew;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.BufWrNew;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes => 0;
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
|
|||
private bool _captureResult;
|
||||
private bool _disposed;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoInMemoryPipe;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.InMemoryPipe;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes { get; }
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
|
|||
private bool _captureResult;
|
||||
private bool _disposed;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoInMemoryRaw;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.InMemoryRaw;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes { get; }
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
|
|||
private bool _captureResult; // toggle: when true, ConsumeLoop stores result; otherwise discards
|
||||
private bool _disposed;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoNamedPipe;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.NamedPipe;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes { get; }
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
|
|||
private bool _captureResult; // toggle: when true, ConsumerLoop stores result; otherwise discards
|
||||
private bool _disposed;
|
||||
|
||||
public string Engine => Configuration.EngineAcBinary;
|
||||
public string IoMode => Configuration.IoNamedPipeRaw;
|
||||
public string DispatchMode => _options.UseGeneratedCode ? Configuration.ModeSGen : Configuration.ModeRuntime;
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.AcBinary;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.NamedPipeRaw;
|
||||
public BenchmarkDispatchMode DispatchMode => _options.UseGeneratedCode ? BenchmarkDispatchMode.SGen : BenchmarkDispatchMode.Runtime;
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes { get; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
namespace AyCode.Core.Serializers.Console.Benchmarks;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer engine identifier — replaces the prior <c>Configuration.EngineXxx</c> string constants
|
||||
/// with a type-safe enum. The benchmark-result <c>Engine</c> column uses <see cref="ToDisplay"/> for
|
||||
/// the human-readable form.
|
||||
/// </summary>
|
||||
internal enum BenchmarkEngine
|
||||
{
|
||||
AcBinary,
|
||||
MemoryPack,
|
||||
#if !AYCODE_NATIVEAOT
|
||||
MessagePack,
|
||||
#endif
|
||||
SystemTextJson,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// I/O mode identifier — replaces the prior <c>Configuration.IoXxx</c> string constants. Note that
|
||||
/// <see cref="NamedPipe"/> and <see cref="NamedPipeRaw"/> share the display string <c>"NamedPipe"</c>
|
||||
/// (they distinguish chunked-framed vs raw-byte[] semantics, but render identically in the IO column);
|
||||
/// the same applies to <see cref="InMemoryPipe"/> + <see cref="InMemoryRaw"/> (<c>"Pipe(in-mem)"</c>).
|
||||
/// </summary>
|
||||
internal enum BenchmarkIoMode
|
||||
{
|
||||
ByteArray,
|
||||
BufWrReuse,
|
||||
BufWrNew,
|
||||
String,
|
||||
NamedPipe,
|
||||
NamedPipeRaw,
|
||||
InMemoryPipe,
|
||||
InMemoryRaw,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatch mode identifier — replaces the prior <c>Configuration.ModeXxx</c> string constants.
|
||||
/// Describes how property access / type dispatch happens for a given benchmark row:
|
||||
/// <list type="bullet">
|
||||
/// <item><see cref="SGen"/> — compile-time source generator path (Unsafe.As<T> direct fields, slot-array wrapper lookup).</item>
|
||||
/// <item><see cref="Runtime"/> — reflection / compiled-delegate path.</item>
|
||||
/// <item><see cref="Hybrid"/> — SGen root with non-SGen child types reached via bridge methods (see docs/BINARY/BINARY_SGEN.md).</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
internal enum BenchmarkDispatchMode
|
||||
{
|
||||
SGen,
|
||||
Runtime,
|
||||
Hybrid,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display-string converters for the benchmark enums. Renders enum values into the column-friendly
|
||||
/// human-readable form used by the per-row console table, the <c>.log</c> file CSV/formatted output,
|
||||
/// and the <c>.LLM</c> markdown table. Centralised here so every output formatter renders identically.
|
||||
/// </summary>
|
||||
internal static class BenchmarkEnumExtensions
|
||||
{
|
||||
internal static string ToDisplay(this BenchmarkEngine engine) => engine switch
|
||||
{
|
||||
BenchmarkEngine.AcBinary => "AcBinary",
|
||||
BenchmarkEngine.MemoryPack => "MemoryPack",
|
||||
#if !AYCODE_NATIVEAOT
|
||||
BenchmarkEngine.MessagePack => "MessagePack",
|
||||
#endif
|
||||
BenchmarkEngine.SystemTextJson => "System.Text.Json",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(engine), engine, null),
|
||||
};
|
||||
|
||||
internal static string ToDisplay(this BenchmarkIoMode mode) => mode switch
|
||||
{
|
||||
BenchmarkIoMode.ByteArray => "Byte[]",
|
||||
BenchmarkIoMode.BufWrReuse => "BufWr reuse",
|
||||
BenchmarkIoMode.BufWrNew => "BufWr new",
|
||||
BenchmarkIoMode.String => "String",
|
||||
BenchmarkIoMode.NamedPipe => "NamedPipe",
|
||||
BenchmarkIoMode.NamedPipeRaw => "NamedPipe",
|
||||
BenchmarkIoMode.InMemoryPipe => "Pipe(in-mem)",
|
||||
BenchmarkIoMode.InMemoryRaw => "Pipe(in-mem)",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null),
|
||||
};
|
||||
|
||||
internal static string ToDisplay(this BenchmarkDispatchMode mode) => mode switch
|
||||
{
|
||||
BenchmarkDispatchMode.SGen => "SGen",
|
||||
BenchmarkDispatchMode.Runtime => "Runtime",
|
||||
BenchmarkDispatchMode.Hybrid => "Hybrid",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null),
|
||||
};
|
||||
}
|
||||
|
|
@ -13,16 +13,16 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal interface ISerializerBenchmark
|
||||
{
|
||||
/// <summary>Serializer engine — e.g. "AcBinary", "MemoryPack", "MessagePack".</summary>
|
||||
string Engine { get; }
|
||||
/// <summary>I/O mode — e.g. "Byte[]", "BufWr reuse", "BufWr new", "NamedPipe", "FileStream".</summary>
|
||||
string IoMode { get; }
|
||||
/// <summary>Dispatch mode — "SGen", "Runtime", or "Hybrid". For AcBinary derived from <c>UseGeneratedCode</c> + child-type SGen coverage; non-AcBinary engines report their own native dispatch model.</summary>
|
||||
string DispatchMode { get; }
|
||||
/// <summary>Options preset name — e.g. "FastMode", "Default", "NoIntern", "WithCompression".</summary>
|
||||
/// <summary>Serializer engine — typed enum, see <see cref="BenchmarkEnumExtensions.ToDisplay(BenchmarkEngine)"/> for the human-readable form.</summary>
|
||||
BenchmarkEngine Engine { get; }
|
||||
/// <summary>I/O mode — typed enum, see <see cref="BenchmarkEnumExtensions.ToDisplay(BenchmarkIoMode)"/> for the human-readable form.</summary>
|
||||
BenchmarkIoMode IoMode { get; }
|
||||
/// <summary>Dispatch mode — typed enum (<see cref="BenchmarkDispatchMode.SGen"/> / <see cref="BenchmarkDispatchMode.Runtime"/> / <see cref="BenchmarkDispatchMode.Hybrid"/>). For AcBinary derived from <c>UseGeneratedCode</c> + child-type SGen coverage; non-AcBinary engines report their own native dispatch model.</summary>
|
||||
BenchmarkDispatchMode DispatchMode { get; }
|
||||
/// <summary>Options preset name — e.g. "FastMode", "Default", "NoIntern", "WithCompression". Stays string because preset names are open-ended (per-instance constructor argument).</summary>
|
||||
string OptionsPreset { get; }
|
||||
/// <summary>Synthesized display name from Engine + IoMode + OptionsPreset.</summary>
|
||||
string Name => $"{Engine} ({IoMode}, {OptionsPreset})";
|
||||
string Name => $"{Engine.ToDisplay()} ({IoMode.ToDisplay()}, {OptionsPreset})";
|
||||
int SerializedSize { get; }
|
||||
string? OptionsDescription => null;
|
||||
/// <summary>One-time SERIALIZER-side setup allocation cost (e.g., pre-allocated ArrayBufferWriter with internal buffer). Captured in constructor; 0 for byte[] API and Fresh-BufWriter variants.</summary>
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ internal sealed class MemoryPackBenchmark : ISerializerBenchmark
|
|||
private readonly MemoryPackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
public string Engine => Configuration.EngineMemoryPack;
|
||||
public string IoMode => Configuration.IoByteArray;
|
||||
public string DispatchMode => Configuration.ModeSGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.MemoryPack;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.ByteArray;
|
||||
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes => 0;
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
|
|||
private readonly byte[] _serialized;
|
||||
private readonly ArrayBufferWriter<byte> _bufferWriter;
|
||||
|
||||
public string Engine => Configuration.EngineMemoryPack;
|
||||
public string IoMode => Configuration.IoBufWrReuse;
|
||||
public string DispatchMode => Configuration.ModeSGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.MemoryPack;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.BufWrReuse;
|
||||
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes { get; }
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmar
|
|||
private readonly MemoryPackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
public string Engine => Configuration.EngineMemoryPack;
|
||||
public string IoMode => Configuration.IoBufWrNew;
|
||||
public string DispatchMode => Configuration.ModeSGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.MemoryPack;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.BufWrNew;
|
||||
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes => 0;
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ internal sealed class MessagePackBenchmark : ISerializerBenchmark
|
|||
private readonly MessagePackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
public string Engine => Configuration.EngineMessagePack;
|
||||
public string IoMode => Configuration.IoByteArray;
|
||||
public string DispatchMode => Configuration.ModeSGen; // MessagePack uses [MessagePackObject] source-generated formatters (StandardResolver)
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.MessagePack;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.ByteArray;
|
||||
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MessagePack uses [MessagePackObject] source-generated formatters (StandardResolver)
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serialized.Length;
|
||||
public long SetupSerializeAllocBytes => 0;
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
|
|||
private readonly string _serialized;
|
||||
private readonly byte[] _serializedUtf8;
|
||||
|
||||
public string Engine => Configuration.EngineSystemTextJson;
|
||||
public string IoMode => Configuration.IoString;
|
||||
public string DispatchMode => Configuration.ModeRuntime; // System.Text.Json default uses reflection-based metadata (no source generator opt-in here)
|
||||
public BenchmarkEngine Engine => BenchmarkEngine.SystemTextJson;
|
||||
public BenchmarkIoMode IoMode => BenchmarkIoMode.String;
|
||||
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.Runtime; // System.Text.Json default uses reflection-based metadata (no source generator opt-in here)
|
||||
public string OptionsPreset { get; }
|
||||
public int SerializedSize => _serializedUtf8.Length;
|
||||
public long SetupSerializeAllocBytes => 0;
|
||||
|
|
|
|||
|
|
@ -41,24 +41,7 @@ internal static class Configuration
|
|||
// 1 = Compact, 2 = Fast
|
||||
internal static WireMode SelectedWireMode = WireMode.Compact;
|
||||
|
||||
// Serializer name constants
|
||||
// Engine identifiers (used in Engine column + comparison logic)
|
||||
internal const string EngineAcBinary = "AcBinary";
|
||||
internal const string EngineMemoryPack = "MemoryPack";
|
||||
#if !AYCODE_NATIVEAOT
|
||||
internal const string EngineMessagePack = "MessagePack";
|
||||
#endif
|
||||
internal const string EngineSystemTextJson = "System.Text.Json";
|
||||
|
||||
// IO mode identifiers (used in IO column + comparison logic)
|
||||
internal const string IoByteArray = "Byte[]";
|
||||
internal const string IoBufWrReuse = "BufWr reuse";
|
||||
internal const string IoBufWrNew = "BufWr new";
|
||||
internal const string IoString = "String";
|
||||
internal const string IoNamedPipe = "NamedPipe";
|
||||
internal const string IoNamedPipeRaw = "NamedPipe";
|
||||
internal const string IoInMemoryPipe = "Pipe(in-mem)";
|
||||
internal const string IoInMemoryRaw = "Pipe(in-mem)";
|
||||
// Engine / IO mode / Dispatch mode identifiers → Benchmarks/BenchmarkEnums.cs (typed enums with ToDisplay)
|
||||
|
||||
// Single source of truth for the chunk size used by ALL pipe-related benchmarks (NamedPipe PipeChunk,
|
||||
// NamedPipe PipeRaw, in-memory Pipe, in-memory RawMem) AND the NamedPipe server's inBufferSize/outBufferSize.
|
||||
|
|
@ -67,14 +50,6 @@ internal static class Configuration
|
|||
// overrides across individual benchmark rows.
|
||||
internal const int PipeChunkSize = 4096;
|
||||
|
||||
// Dispatch mode identifiers — describes how property access / type dispatch happens for a given run.
|
||||
// SGen = compile-time source generator path (Unsafe.As<T> direct fields, slot-array wrapper lookup).
|
||||
// Runtime= reflection / compiled-delegate path.
|
||||
// Hybrid = SGen root with non-SGen child types reached via bridge methods. See docs/BINARY/BINARY_SGEN.md.
|
||||
internal const string ModeSGen = "SGen";
|
||||
internal const string ModeRuntime = "Runtime";
|
||||
internal const string ModeHybrid = "Hybrid";
|
||||
|
||||
// Per-cell adaptive iteration target wall-clock duration. Each Ser/Des function calibrates its
|
||||
// own iteration count post-warmup so the sample batch lands in this range — equalizes the
|
||||
// per-sample window across cells of vastly different per-op cost (Small ~6 ns/op vs Large
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using AyCode.Core.Serializers.Binaries;
|
||||
using AyCode.Core.Serializers.Console.Benchmarks;
|
||||
using AyCode.Core.Tests.TestModels;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
|
@ -191,10 +192,10 @@ internal static class Output
|
|||
// Order by per-op µs (iter-independent) — rows may have different iter counts post-calibration.
|
||||
var testResults = results.Where(r => r.TestDataName == testData.DisplayName).OrderBy(r => RtPerOp(r)).ToList();
|
||||
// Baseline switched MessagePack → MemoryPack: MemoryPack is the SOTA performance leader.
|
||||
var memPackResult = testResults.FirstOrDefault(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray));
|
||||
var memPackResult = testResults.FirstOrDefault(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray));
|
||||
// Pin the comparison to AcBinary's SGen variant — apples-to-apples vs MemoryPack (also source-generated).
|
||||
// The Runtime variant is shown alongside in the table for context, not used as the headline number.
|
||||
var acBinaryResult = testResults.FirstOrDefault(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen));
|
||||
var acBinaryResult = testResults.FirstOrDefault(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen));
|
||||
|
||||
System.Console.WriteLine($"\n┌─ {testData.DisplayName} ─".PadRight(172, '─') + "┐");
|
||||
// Header-only units; per-row entries are numbers (µs/op for time, KB/op for alloc, KB pair "ser / des" for Setup, B for Size).
|
||||
|
|
@ -215,8 +216,8 @@ internal static class Output
|
|||
|
||||
// Highlight MemoryPack baseline (any Byte[]) and AcBinary headline contender (Byte[] + SGen) with win/lose colors.
|
||||
// The AcBinary Byte[]+Runtime variant is shown unhighlighted — it's contextual (SGen speed-up reference), not the headline.
|
||||
var isHighlighted = (result.Engine == Configuration.EngineMemoryPack && result.IoMode == Configuration.IoByteArray)
|
||||
|| (result.Engine == Configuration.EngineAcBinary && result.IoMode == Configuration.IoByteArray && result.DispatchMode == Configuration.ModeSGen);
|
||||
var isHighlighted = (result.Engine == BenchmarkEngine.MemoryPack && result.IoMode == BenchmarkIoMode.ByteArray)
|
||||
|| (result.Engine == BenchmarkEngine.AcBinary && result.IoMode == BenchmarkIoMode.ByteArray && result.DispatchMode == BenchmarkDispatchMode.SGen);
|
||||
|
||||
var prefix = isHighlighted ? "│►" : "│ ";
|
||||
var suffix = isHighlighted ? "◄│" : " │";
|
||||
|
|
@ -224,7 +225,7 @@ internal static class Output
|
|||
// Color logic: Green = winner (faster), Red = loser (slower)
|
||||
if (isHighlighted && memPackResult != null && acBinaryResult != null)
|
||||
{
|
||||
var isMemPack = (result.Engine == Configuration.EngineMemoryPack && result.IoMode == Configuration.IoByteArray);
|
||||
var isMemPack = (result.Engine == BenchmarkEngine.MemoryPack && result.IoMode == BenchmarkIoMode.ByteArray);
|
||||
var memPackFaster = RtPerOp(memPackResult) < RtPerOp(acBinaryResult);
|
||||
|
||||
if (isMemPack)
|
||||
|
|
@ -237,7 +238,7 @@ internal static class Output
|
|||
}
|
||||
}
|
||||
|
||||
System.Console.WriteLine($"{prefix}{rank++,4} │ {result.Engine,-11} │ {result.OptionsPreset,-22} │ {result.IoMode,-12} │ {result.DispatchMode,-8} │ {setup,14} │ {size,8} │ {ser,10} │ {serAlloc,10} │ {des,10} │ {desAlloc,10} │ {rt,10} │ {rtAlloc,10}{suffix}");
|
||||
System.Console.WriteLine($"{prefix}{rank++,4} │ {result.Engine.ToDisplay(),-11} │ {result.OptionsPreset,-22} │ {result.IoMode.ToDisplay(),-12} │ {result.DispatchMode.ToDisplay(),-8} │ {setup,14} │ {size,8} │ {ser,10} │ {serAlloc,10} │ {des,10} │ {desAlloc,10} │ {rt,10} │ {rtAlloc,10}{suffix}");
|
||||
|
||||
if (isHighlighted)
|
||||
{
|
||||
|
|
@ -366,13 +367,13 @@ internal static class Output
|
|||
System.Console.WriteLine($"{"Fastest Round-trip",-20} │ {fastestRt.Name,-40} │ {fastestRt.AvgPerOp,12:F2} µs/op");
|
||||
|
||||
// Overall AcBinary (SGen) vs MemoryPack comparison.
|
||||
var memPackSerResults = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray) && r.SerializeTimeMs > 0).ToList();
|
||||
var memPackDesResults = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray) && r.DeserializeTimeMs > 0).ToList();
|
||||
var memPackRtResults = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray) && r.RoundTripTimeMs > 0).ToList();
|
||||
var memPackSerResults = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray) && r.SerializeTimeMs > 0).ToList();
|
||||
var memPackDesResults = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray) && r.DeserializeTimeMs > 0).ToList();
|
||||
var memPackRtResults = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray) && r.RoundTripTimeMs > 0).ToList();
|
||||
|
||||
var acBinarySerResults = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen) && r.SerializeTimeMs > 0).ToList();
|
||||
var acBinaryDesResults = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen) && r.DeserializeTimeMs > 0).ToList();
|
||||
var acBinaryRtResults = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen) && r.RoundTripTimeMs > 0).ToList();
|
||||
var acBinarySerResults = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen) && r.SerializeTimeMs > 0).ToList();
|
||||
var acBinaryDesResults = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen) && r.DeserializeTimeMs > 0).ToList();
|
||||
var acBinaryRtResults = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen) && r.RoundTripTimeMs > 0).ToList();
|
||||
|
||||
// Skip comparison if no data available
|
||||
if (memPackRtResults.Count == 0 || acBinaryRtResults.Count == 0)
|
||||
|
|
@ -384,8 +385,8 @@ internal static class Output
|
|||
}
|
||||
|
||||
// All averages are over per-op µs (iter-independent). Three aggregations per metric.
|
||||
var sizeAcResults = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen)).ToList();
|
||||
var sizeMpResults = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray)).ToList();
|
||||
var sizeAcResults = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen)).ToList();
|
||||
var sizeMpResults = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray)).ToList();
|
||||
|
||||
var serStats = ComputeOverallStats(acBinarySerResults, memPackSerResults, SerPerOp);
|
||||
var desStats = ComputeOverallStats(acBinaryDesResults, memPackDesResults, DesPerOp);
|
||||
|
|
@ -472,7 +473,7 @@ internal static class Output
|
|||
var testResults = results.Where(r => r.TestDataName == testData.DisplayName).ToList();
|
||||
foreach (var result in testResults)
|
||||
{
|
||||
sb.AppendLine($"{result.TestDataName},{result.Engine},{result.IoMode},{result.DispatchMode},{result.OptionsPreset},{result.SerializedSize},{SerPerOp(result):F2},{DesPerOp(result):F2},{RtPerOp(result):F2},{result.SerializeAllocBytesPerOp},{result.DeserializeAllocBytesPerOp},{result.RoundTripAllocBytesPerOp},{result.SetupSerializeAllocBytes},{result.SetupDeserializeAllocBytes}");
|
||||
sb.AppendLine($"{result.TestDataName},{result.Engine.ToDisplay()},{result.IoMode.ToDisplay()},{result.DispatchMode.ToDisplay()},{result.OptionsPreset},{result.SerializedSize},{SerPerOp(result):F2},{DesPerOp(result):F2},{RtPerOp(result):F2},{result.SerializeAllocBytesPerOp},{result.DeserializeAllocBytesPerOp},{result.RoundTripAllocBytesPerOp},{result.SetupSerializeAllocBytes},{result.SetupDeserializeAllocBytes}");
|
||||
}
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
|
@ -486,8 +487,8 @@ internal static class Output
|
|||
{
|
||||
// Order by per-op µs (iter-independent) — rows may have different iter counts post-calibration.
|
||||
var testResults = results.Where(r => r.TestDataName == testData.DisplayName).OrderBy(r => RtPerOp(r)).ToList();
|
||||
var memPackResult = testResults.FirstOrDefault(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray));
|
||||
var acBinaryResult = testResults.FirstOrDefault(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen));
|
||||
var memPackResult = testResults.FirstOrDefault(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray));
|
||||
var acBinaryResult = testResults.FirstOrDefault(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen));
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"--- {testData.DisplayName} ---");
|
||||
|
|
@ -497,7 +498,7 @@ internal static class Output
|
|||
var rank = 1;
|
||||
foreach (var result in testResults)
|
||||
{
|
||||
var isHighlighted = ((result.Engine == Configuration.EngineMemoryPack || result.Engine == Configuration.EngineAcBinary) && result.IoMode == Configuration.IoByteArray);
|
||||
var isHighlighted = ((result.Engine == BenchmarkEngine.MemoryPack || result.Engine == BenchmarkEngine.AcBinary) && result.IoMode == BenchmarkIoMode.ByteArray);
|
||||
var prefix = isHighlighted ? "► " : " ";
|
||||
|
||||
var size = $"{result.SerializedSize:N0}";
|
||||
|
|
@ -527,13 +528,13 @@ internal static class Output
|
|||
sb.AppendLine();
|
||||
sb.AppendLine("=== AcBinary (Byte[], SGen) vs MemoryPack (Byte[]) (Overall) ===");
|
||||
|
||||
var memPackSerResults2 = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray) && r.SerializeTimeMs > 0).ToList();
|
||||
var memPackDesResults2 = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray) && r.DeserializeTimeMs > 0).ToList();
|
||||
var memPackRtResults2 = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray) && r.RoundTripTimeMs > 0).ToList();
|
||||
var memPackSerResults2 = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray) && r.SerializeTimeMs > 0).ToList();
|
||||
var memPackDesResults2 = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray) && r.DeserializeTimeMs > 0).ToList();
|
||||
var memPackRtResults2 = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray) && r.RoundTripTimeMs > 0).ToList();
|
||||
|
||||
var acBinarySerResults2 = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen) && r.SerializeTimeMs > 0).ToList();
|
||||
var acBinaryDesResults2 = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen) && r.DeserializeTimeMs > 0).ToList();
|
||||
var acBinaryRtResults2 = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen) && r.RoundTripTimeMs > 0).ToList();
|
||||
var acBinarySerResults2 = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen) && r.SerializeTimeMs > 0).ToList();
|
||||
var acBinaryDesResults2 = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen) && r.DeserializeTimeMs > 0).ToList();
|
||||
var acBinaryRtResults2 = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen) && r.RoundTripTimeMs > 0).ToList();
|
||||
|
||||
// Skip comparison block if either side has no Byte[] data
|
||||
if (memPackRtResults2.Count == 0 || acBinaryRtResults2.Count == 0)
|
||||
|
|
@ -547,8 +548,8 @@ internal static class Output
|
|||
return;
|
||||
}
|
||||
|
||||
var sizeAcResults2 = results.Where(r => (r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen)).ToList();
|
||||
var sizeMpResults2 = results.Where(r => (r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray)).ToList();
|
||||
var sizeAcResults2 = results.Where(r => (r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen)).ToList();
|
||||
var sizeMpResults2 = results.Where(r => (r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray)).ToList();
|
||||
|
||||
AppendOverallLine(sb, "Serialize", "µs/op", ComputeOverallStats(acBinarySerResults2, memPackSerResults2, SerPerOp));
|
||||
AppendOverallLine(sb, "Ser Alloc", "B/op", ComputeOverallStats(acBinarySerResults2, memPackSerResults2, r => r.SerializeAllocBytesPerOp), "F0");
|
||||
|
|
@ -620,13 +621,13 @@ internal static class Output
|
|||
var iterCol = r.IsRoundTripOnly
|
||||
? r.RoundTripIterations.ToString(inv)
|
||||
: $"{(r.SerializeIterations > 0 ? r.SerializeIterations.ToString(inv) : "-")} / {(r.DeserializeIterations > 0 ? r.DeserializeIterations.ToString(inv) : "-")}";
|
||||
sb.AppendLine($"{r.TestDataName} | {r.Engine} | {r.IoMode} | {r.DispatchMode} | {r.OptionsPreset} | {r.SerializedSize} | {ser} | {des} | {rt} | {serAlloc} | {desAlloc} | {rtAlloc} | {setupAlloc} | {iterCol}");
|
||||
sb.AppendLine($"{r.TestDataName} | {r.Engine.ToDisplay()} | {r.IoMode.ToDisplay()} | {r.DispatchMode.ToDisplay()} | {r.OptionsPreset} | {r.SerializedSize} | {ser} | {des} | {rt} | {serAlloc} | {desAlloc} | {rtAlloc} | {setupAlloc} | {iterCol}");
|
||||
}
|
||||
}
|
||||
|
||||
// Overall AcBinary (SGen, Byte[]) vs MemoryPack (Byte[]) comparison
|
||||
var memPackByteArrayResults = results.Where(r => r.Engine == Configuration.EngineMemoryPack && r.IoMode == Configuration.IoByteArray).ToList();
|
||||
var acBinarySGenByteArrayResults = results.Where(r => r.Engine == Configuration.EngineAcBinary && r.IoMode == Configuration.IoByteArray && r.DispatchMode == Configuration.ModeSGen).ToList();
|
||||
var memPackByteArrayResults = results.Where(r => r.Engine == BenchmarkEngine.MemoryPack && r.IoMode == BenchmarkIoMode.ByteArray).ToList();
|
||||
var acBinarySGenByteArrayResults = results.Where(r => r.Engine == BenchmarkEngine.AcBinary && r.IoMode == BenchmarkIoMode.ByteArray && r.DispatchMode == BenchmarkDispatchMode.SGen).ToList();
|
||||
var memPackSerResultsLlm = memPackByteArrayResults.Where(r => r.SerializeTimeMs > 0).ToList();
|
||||
var memPackDesResultsLlm = memPackByteArrayResults.Where(r => r.DeserializeTimeMs > 0).ToList();
|
||||
var memPackRtResultsLlm = memPackByteArrayResults.Where(r => r.RoundTripTimeMs > 0).ToList();
|
||||
|
|
|
|||
Loading…
Reference in New Issue