AyCode.Core/AyCode.Benchmark
Loretta cf92370bea Refactor AcBinarySerializer to use declared type dispatch
- All serialization APIs now use the declared type (typeof(T) or explicit Type) for dispatch, not value.GetType()
- Added non-generic overloads for Serialize, SerializeChunked, and SerializeChunkedFramed with Type parameter for runtime scenarios
- ScanForDuplicates accepts optional TypeMetadataWrapper to avoid redundant lookups
- Simplified generated writer path and improved wrapper usage
- Benchmarks updated to use new API and cache serialized data
- Minor cleanups: removed unused usings, improved comments, inlined logic
- Ensures consistent, predictable, and more performant type dispatch across all serialization entry points
2026-05-26 07:56:25 +02:00
..
Reporting SGen null-handling parity, micro-opt CV, doc & bench fixes 2026-05-24 07:39:21 +02:00
Workloads/Scenarios Refactor AcBinarySerializer to use declared type dispatch 2026-05-26 07:56:25 +02:00
AcBinaryVsMemPackBenchmark.cs Refactor AcBinary string marker dispatch & add JIT harness 2026-05-20 12:49:43 +02:00
AyCode.Benchmark.csproj Add SGenOnly build config and centralize build settings 2026-05-19 17:41:06 +02:00
BdnSummaryAdapter.cs SGen null-handling parity, micro-opt CV, doc & bench fixes 2026-05-24 07:39:21 +02:00
JitDisassemblyBenchmark.cs Refactor AcBinary string marker dispatch & add JIT harness 2026-05-20 12:49:43 +02:00
Program.cs Refactor AcBinary string marker dispatch & add JIT harness 2026-05-20 12:49:43 +02:00
README.md Refactor: BDN runner, unified reporting, doc overhaul 2026-05-15 20:54:42 +02:00
RefForeachBenchmark.cs Refactor serialization infra, add perf benchmarks 2025-12-30 19:29:39 +01:00
SignalRCommunicationBenchmarks.cs [LOADED_DOCS: 2 files, no new loads] 2026-05-13 08:40:42 +02:00
SignalRRoundTripBenchmarks.cs [LOADED_DOCS: 2 files, no new loads] 2026-05-13 08:40:42 +02:00
SourceGeneratorBenchmarks.cs Refactor serializer options, string fast paths & analysis 2026-01-25 16:40:40 +01:00
TaskHelperBenchmarks.cs Rename BenchmarkSuite1 to AyCode.Benchmark project 2025-12-13 10:11:39 +01:00
ValueTypePassingBenchmark.cs Refactor serialization infra, add perf benchmarks 2025-12-30 19:29:39 +01:00

README.md

AyCode.Benchmark

BenchmarkDotNet performance suite plus the shared workload / reporting infrastructure used by both BDN and the Console runner. Targets .NET 9.

Role: dual-purpose project

This project plays two roles:

  1. BDN runner Exe — standalone benchmark host (Program.cs + [Benchmark]-decorated classes). Invoke via dotnet run -c Release --project AyCode.Benchmark -- <switch>.
  2. Shared workload + reporting library — exposes public types under Workloads/Scenarios/ and Reporting/ that AyCode.Core.Serializers.Console consumes via <ProjectReference>.

Both runners feed the SAME ISerializerBenchmark workload (same test data graphs, same wire options, same payload sizes) — so Console's adaptive-engine numbers and BDN's iteration-based numbers are directly comparable.

Output convention

Both runners emit a unified .log / .LLM / .output triplet to Test_Benchmark_Results/Benchmark/ (resolved at runtime via walk-up to the nearest AyCode.Core.sln — worktree-aware):

File Source Content
Console.FullBenchmark_<Build>_<ts>.log Console runner Human-readable formatted view
Console.FullBenchmark_<Build>_<ts>.LLM Console runner Markdown table, LLM-paste-friendly
Console.FullBenchmark_<Build>_<ts>.output Console runner Hex dump of Large cell binary
Bdn.FullBenchmark_<Build>_<ts>.log BDN runner Same format as Console
Bdn.FullBenchmark_<Build>_<ts>.LLM BDN runner Same
Bdn.FullBenchmark_<Build>_<ts>.output BDN runner Same

BDN-native artifacts (BDN's own reports, raw measurements, run logs) go to Test_Benchmark_Results/Benchmark/BDN/ — kept separate so the unified Console+BDN .log/.LLM/.output triplet stays uncluttered.

Architecture

┌────────────────────────────────────────────────────────────────┐
│ AyCode.Benchmark (this project)                                │
│                                                                 │
│  Workloads/Scenarios/    public — shared workload types        │
│    ISerializerBenchmark, BenchmarkOptions, BenchmarkEnums,     │
│    AcBinaryBenchmark<T>, MemoryPackBenchmark<T>,               │
│    AcBinaryBufferWriterBenchmark<T>, ... (12 concretes),       │
│    RoundTripValidator                                           │
│                                                                 │
│  Reporting/              public — shared reporting types       │
│    BenchmarkResult, ReportingContext, BenchmarkReportWriter    │
│                                                                 │
│  AcBinaryVsMemPackBenchmark.cs   BDN [Benchmark] class          │
│                                  (mirrors Console "F" menu)    │
│  BdnSummaryAdapter.cs            Summary → BenchmarkResult →   │
│                                  BenchmarkReportWriter.SaveAll │
│  Program.cs              BDN entry + CLI dispatch              │
│                                                                 │
│  + KEEP: JitDisassemblyBenchmark, RefForeachBenchmark,         │
│          TaskHelperBenchmarks, ValueTypePassingBenchmark,      │
│          SourceGeneratorBenchmarks,                            │
│          SignalRCommunicationBenchmarks,                       │
│          SignalRRoundTripBenchmarks                            │
└────────────────────────────────────────────────────────────────┘
                              ▲
                              │ ProjectReference (one-way)
                              │
┌────────────────────────────────────────────────────────────────┐
│ AyCode.Core.Serializers.Console                                │
│                                                                 │
│  BenchmarkLoop.cs        custom adaptive measure engine        │
│    (CPU 0 pin, High priority, phase-isolated warmup,           │
│    10-sample median + pilot, ~250ms/cell calibration)          │
│  Menu.cs / Configuration.cs / Program.cs    Console UX         │
│                                                                 │
│  Uses Benchmark's:                                             │
│   - Workloads/Scenarios/* (interface + concrete benchmarks)    │
│   - Reporting/BenchmarkReportWriter (SaveAll, Print...)        │
└────────────────────────────────────────────────────────────────┘

Two runners — same workload, different measurement engines

Aspect Console (custom engine) BDN
Use case Fast iteration during micro-opt loops Statistically confident before-commit validation
Measurement Adaptive per-cell iter (target ~250ms), 10 samples + pilot, median Warmup + N iterations, outlier removal, JIT-stabilized, process-spawn isolation
Time per full run ~1-3 min ~5-15 min
Noise floor ~3-5% inter-engine delta visible ~1-2%
Output format Identical (same BenchmarkReportWriter writes both)

The Console and BDN outputs use the SAME BenchmarkResult DTO and the SAME formatter, so cells are directly comparable: pick a cell in Console.FullBenchmark_*.LLM, find the same cell in Bdn.FullBenchmark_*.LLM — deltas should agree within BDN's tighter CI.

CLI

dotnet run -c Release --project AyCode.Benchmark -- <switch>
Switch Description
--serializers AcBinary FastMode Byte[] vs MemoryPack Default Byte[] across 5 TestData cells (mirrors Console "F" menu / FastestByte). Emits Bdn.FullBenchmark_*.{log,LLM,output} + BDN-native artifacts under BDN/.
--jitasm JIT disassembly analysis (x64 asm of serialize/deserialize hot path).
--quick Quick inline benchmark (custom Stopwatch-based, not BDN).
--test / --testmsgpack Quick smoke tests.
--save-coverage <file> Save coverage file into Test_Benchmark_Results/CoverageReport/.
(no args) Interactive BenchmarkSwitcher — pick from all [Benchmark] classes in the assembly.

Key files

Serializer benchmark stack (the refactor scope)

  • AcBinaryVsMemPackBenchmark.cs — BDN [MemoryDiagnoser] class. [ParamsSource](TestData = Small/Medium/Large/Repeated/Deep) × [Params](Engine = AcBinary/MemoryPack). [GlobalSetup] hidrátálja a Workloads scenario-ját + round-trip-verify.
  • BdnSummaryAdapter.csSummary → List<BenchmarkResult> translator (groups per (TestData × Engine), ns → ms conversion, GcStats → allocated-bytes-per-op). Calls BenchmarkReportWriter.PrintGroupedResults + SaveAll(ctx with SourceTag="Bdn", ...).
  • Program.cs — BDN entry. Sets global WithArtifactsPath(.../Benchmark/BDN); --serializers switch wires BenchmarkRunner.Run<AcBinaryVsMemPackBenchmark> + adapter.
  • Workloads/Scenarios/ — shared workload types (see folder README).
  • Reporting/ — shared reporting types (see folder README).

KEEP benchmarks (independent — not in the serializer-refactor scope)

Dependencies

Dependency Purpose
BenchmarkDotNet BDN harness
MemoryPack Comparison target (used by Workloads scenarios + BDN class)
MessagePack Comparison target (KEEP benchmarks + Workloads MessagePackBenchmark scenario)
MongoDB.Bson KEEP-side comparison target
Microsoft.VisualStudio.DiagnosticsHub.BenchmarkDotNetDiagnosers VS Profiler integration
AyCode.Core (ProjectReference) AcBinary serializer
AyCode.Core.Tests (ProjectReference) Test data factory (TestDataFactory, TestOrder_All_False/True, BenchmarkTestDataProvider*)
AyCode.Core.Serializers.SourceGenerator (Analyzer-only) SGen for [AcBinarySerializable]-tagged types