Refactored string property deserialization to separate hot (common, no-feature) and cold (feature-engaged) marker handling, improving JIT inlining and cold-start performance. Introduced `TryReadStringProperty` (hot, inlined) and `TryReadStringColdPath` (cold, optimized) methods. Updated method attributes for better JIT control and clarified WASM string-cache dead code. Added `BINARY_BYTECODE_OPTIMIZATION.md` and updated related docs. Removed AutoMapper, updated logging package versions, and adjusted project files and settings accordingly.
Added WithProcessStabilization to pin CPU affinity and raise process priority for all BDN entry points, matching Console runner stabilization. Benchmark results are now ordered by Engine then RtPerOp for stable, diff-friendly output. Report headers clarify when BDN manages run parameters. Enhanced comments for clarity; no changes to benchmark logic.
- Introduce BDN-based runner (AcBinaryVsMemPackBenchmark) mirroring Console's FastestByte scenario; add BdnSummaryAdapter for unified result translation.
- Standardize output: both runners emit .log/.LLM/.output triplets; BDN-native artifacts go under Benchmark/BDN/.
- Simplify CLI: replace granular switches with --serializers; update help and usage.
- Remove legacy benchmark classes; focus on scenario-based approach.
- Rewrite README.md for both AyCode.Benchmark and Console to document dual-runner architecture, output conventions, and dependencies.
- Rotate BINARY_TODO.md; archive closed entries to BINARY_TODO_2026_04.md and BINARY_TODO_2026_05.md.
- Add BINARY_SGEN_OPTIMIZATION.md for SGen per-property emit optimization notes.
- Update comments and docstrings for clarity and maintainability; clarify BenchmarkResult iteration semantics for BDN rows.
- Removed Output.cs and migrated all reporting, formatting, and statistics logic to a new BenchmarkReportWriter static class.
- Extended ReportingContext with run-header fields for richer output metadata.
- Updated BenchmarkLoop to use BenchmarkReportWriter and the new ReportingContext.
- Centralized all output file generation (.log, .LLM, .output) and formatting helpers in BenchmarkReportWriter.
- Improved separation of concerns and unified output artifact naming and metadata.
Major refactor: all benchmark engine implementations, enums, and helpers moved from Console project to AyCode.Core.Benchmarks.Workloads.Scenarios for unified cross-runner use. BenchmarkResult and reporting logic moved to AyCode.Core.Benchmarks.Reporting. Attribute-flag aggregation centralized in BenchmarkOptions. Updated all usages, project references, and SGen codegen for ref-handling. Prepares codebase for shared reporting and future extensibility.
Split AcBinarySourceGenerator.cs into multiple partial class files for improved maintainability and clarity. Each major concern (models, type analysis, class info extraction, writer/reader emit, diagnostics, and module init) now resides in its own file. Updated .gitignore and settings.local.json to support the new structure. No functional changes to generator output; this is a pure organizational refactor.
Refactored several methods to use ternary operators and single-line returns for early-exit and exception cases. Improved code readability by condensing multi-line if/else and null checks into concise expressions. No changes to functionality.
Moved StringSmall/Medium/Big/Ascii readers from static helpers in AcBinaryDeserializer to instance methods on BinaryDeserializationContext. Updated all call sites (runtime, SGen, type reader table) to use the new methods. Improved documentation, clarified wire format handling, and added a corrupted-wire guard for StringBig. Removes duplication and centralizes string wire-decode logic.
- Moved interned string decode logic to BinaryDeserializationContext instance methods, reducing duplication and unifying SGen, runtime, and cross-type paths.
- Updated SGen-emitted code and TypeReaderTable to use new context methods.
- Added performance TODO (ACCORE-BIN-T-K9M3) documenting rationale and acceptance.
- Clarified AcBinarySerializableAttribute XML docs.
- Added repo-scoped nuget.config for deterministic restore.
- Updated settings.local.json with new Bash/dev commands.
- Minor code and comment cleanups for clarity.
Add per-type EnablePolymorphDetectFeature flag
Replaces the global UsePolymorphType constant with a per-type EnablePolymorphDetectFeature flag on AcBinarySerializableAttribute. The source generator now emits or omits polymorphic type info for System.Object properties based on this flag, defaulting to enabled. Updates diagnostics, documentation, and SerializableClassInfo to support this feature, clarifying the risks of disabling it and improving attribute XML docs for all feature flags.
Rename ShallowCopy to FlatCopy, add polymorph support
- Renamed all "ShallowCopy" serializer presets and references to "FlatCopy" for clarity and consistency.
- Expanded documentation to clarify flat serialization use cases, especially for delta-update and partial-write scenarios.
- Added EnablePolymorphDetectFeature to AcBinarySerializableAttribute and updated all constructor overloads.
- Set UsePolymorphType = true in AcBinarySourceGenerator to enable polymorphic type support by default.
- Updated all [AcBinarySerializable(...)] usages to include new feature flags, explicitly disabling property filter and polymorph detection for affected types.
- Improved comments and documentation for maintainability.
Add compile-time error for object-typed props w/o polymorph
Introduces ACBIN002: a compile-time diagnostic that errors if a [AcBinarySerializable] type declares a System.Object property while UsePolymorphType is false. This prevents silent wire corruption by requiring the developer to either enable polymorphic serialization, use a concrete type, or ignore the property. The check is integrated into the source generator initialization.
- Introduce `MaxDepthBehavior` option (`Throw`, `Truncate`, `Disable`) for explicit depth-limit handling in AcBinarySerializer and SGen.
- Default is now `Throw` (fail-fast); `ShallowCopy` preset uses `Truncate` for shallow-copy semantics.
- Refactor runtime and SGen paths to use unified `TryEnterRecursion`/`ExitRecursion` for correct wire output and inc/dec symmetry.
- Add focused tests to diagnose SGen+Truncate wire-misalignment bug (see `BINARY_ISSUES.md#accore-bin-i-t7k3`).
- Update docs and comments to clarify new behavior and document Toon serializer's current lack of `MaxDepthBehavior` support.
- Adjust tests and usages for new semantics and improved safety.
Introduced MaxDepthBehavior enum and option to control recursion depth handling (Truncate, Throw, Disable) in AcSerializerOptions. Refactored depth-check logic to use a precomputed NeedsDepthCheck flag. Enhanced exception messages for depth-limit violations. Updated tests to assert correct exception behavior for cycles. Improved documentation and added new test/log commands in settings.local.json.
Refactored AcBinary, AcJson, and AcToon serializers to eliminate the explicit depth parameter from all serialization/deserialization methods, generated code, and interfaces. Introduced a global RecursionDepth field on the serialization context, incremented/decremented at recursion entry/exit, and enforced against MaxDepth as a safety net (except when ReferenceHandling=All). Updated all usages, including property, array, and dictionary handling, to use the new context-based depth tracking. Ensured consistency across runtime and generated code.
Refactored WriteByte, WriteVarUInt, and WriteVarULong to use a new GrowOne helper for single-byte buffer growth. This moves the Output.Grow call out of the hot path, improving inlining and serialization performance for frequent single-byte writes. Added detailed comments explaining the rationale and AOT benefits.
The "Test Type" (TypeName) field was removed from all benchmark output locations, including console summaries, formatted output, and markdown result files. No functional changes were made to the test model definitions; only a BOM was added to SharedTestOrderModels.cs. All other benchmark summary details remain unchanged.
Refactored the benchmark and test data infrastructure to use generic, type-safe, and multi-variant models. Introduced generic base classes for the test data hierarchy and factories, with closing-generic aliases for _All_True and _All_False families. Benchmarks now select the correct test data variant per serializer options, and all serializers are generic over the order type. Output and result reporting now include the CLR type name for clarity. Centralized string property handling and improved documentation throughout.
Refactor tests to use _All_True model types throughout
Replaced all usages of legacy test model types (e.g., TestOrder, TestOrderItem, SharedTag, etc.) with new, feature-complete _All_True variants across SignalR test infrastructure, data sources, and service handlers. Updated all generic constraints, method signatures, and test data to use the new types. Added SharedTestBaseModels.cs and SharedTestOrderModels.cs to define abstract bases and concrete _All_True models with full serialization attributes. This enables more thorough and realistic serialization/deserialization testing and future extensibility.
Refactor benchmark suite to use enums for config
Replaced string parameters for layer, opMode, and serializerMode with strongly-typed enums (BenchmarkLayer, BenchmarkOpMode, SerializerSelectionMode) across BenchmarkLoop, Menu, and Program. Updated CLI parsing and menu logic to use Enum.TryParse and return enums. Added XML docs for new enums. Improves type safety, code clarity, and maintainability.
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.
Refactor: move benchmark logic to BenchmarkLoop.cs
Moved all benchmark execution logic (RunBenchmark, RunBenchmarksForTestData, CreateSerializers) from Program.cs into a new static class BenchmarkLoop in BenchmarkLoop.cs. Program.cs now delegates benchmark runs to BenchmarkLoop, improving separation of concerns. No changes to benchmark functionality.
Moved all ISerializerBenchmark implementations for AcBinary and MemoryPack from Program.cs into dedicated files under Benchmarks/. Improves code organization and maintainability; no logic changes, only file structure refactor.
Refactor: extract serializer benchmarks to separate files
Moved AcBinary, MemoryPack, MessagePack, and SystemTextJson benchmark classes into dedicated files for clarity. Centralized options formatting and MemoryPack selection logic in a new BenchmarkOptions helper. Updated Program.cs to use these helpers and removed redundant inline implementations, improving code organization without changing benchmark logic.
Extract ISerializerBenchmark to its own file
Moved ISerializerBenchmark from Program.cs to a new ISerializerBenchmark.cs file under the AyCode.Core.Serializers.Console.Benchmarks namespace. Updated all benchmark classes in Program.cs to implement the interface from the new namespace and made them internal. Added the necessary using directive to Program.cs. Adjusted a PowerShell script in settings.local.json to ensure the new using is present. Removed the old interface definition from Program.cs.
Refactor: move benchmark loop logic to BenchmarkLoop.cs
Refactored all benchmark execution infrastructure from Program.cs into a new internal static class BenchmarkLoop. This includes timing, allocation measurement, progress reporting, GC helpers, MemoryPack setup validation, and test data filtering. Updated Program.cs and all serializer benchmarks to use the new class. Added serAllocPct reporting in Output.cs and a PowerShell script for automated refactoring. No functional changes to benchmark logic.
Refactor: split Program.cs into Menu, Output, DTO
Refactored the benchmark console app for modularity:
- Moved all menu logic to Menu.cs (main/settings menus)
- Moved all output/result formatting to Output.cs
- Extracted BenchmarkResult DTO to BenchmarkResult.cs
- Program.cs now only handles orchestration and the benchmark loop
- Moved GetCurrentCharsetName to Configuration.cs
- Removed obsolete Warmup methods from serializers
No functional changes; improves clarity and maintainability.
Refactor: centralize config/state in Configuration.cs
Moved all benchmark configuration, mutable state, and attribute-flag aggregation from Program.cs to a new Configuration.cs static class. Updated all references in Program.cs and related benchmark classes to use Configuration.<value>. Removed the "profiler" CLI mode and its code. Updated README.md to reflect these changes. This improves maintainability and keeps Program.cs focused on orchestration and UX, with no changes to benchmark logic.
Refactor output, allocation, and summary logic in Program
- Switched if/else and range checks to C# switch expressions for clarity.
- Improved console progress display with cleaner line updates.
- Added Thread.Sleep after JIT pre-warmup for stable benchmarking.
- Enhanced allocation measurement for serializer/deserializer setup.
- Made options and summary output conditional and more consistent.
- Standardized string outputs and comparison headers.
- Improved comments, XML docs, and code style for maintainability.
- No changes to core algorithms; all changes are quality-of-life and output improvements.
Phase-isolated Ser/Des warmup & GC in benchmarks
Refactored benchmark loop to perform separate warmup and measurement for serialization and deserialization phases, with forced GC.Collect at each phase boundary for heap and cache isolation. Added ForceGcCollect() and new WarmupSerialize/WarmupDeserialize interface methods (with defaults). Updated output, documentation, and per-phase iteration handling for improved accuracy and clarity. Added detailed comments explaining rationale and effects.
AcBinary: add framing doc, buffer growth fixes, doc updates
- Added `BINARY_WHYUSE.md` for architectural framing and value proposition
- Updated `BINARY_FEATURES.md` and `README.md` to reference and prioritize the new doc
- Documented AsyncPipeWriterOutput chunk-size limitation and workarounds in `BINARY_ASYNCPIPE_ISSUES.md`
- Refactored buffer growth logic in `AcBinarySerializer.BinarySerializationContext.cs` to validate capacity after grow and throw clear exceptions on under-provisioning; removed dead method
- Fixed chunk size alignment bug in `AsyncPipeWriterOutput.cs` to prevent buffer under-provisioning
- Added `AYCODE_NATIVEAOT` build config support in `Program.cs`
- Improved documentation clarity and error diagnostics for streaming/buffered serialization edge cases
Enable per-type property filter opt-out in AcBinary
Adds EnablePropertyFilterFeature to AcBinarySerializableAttribute, allowing types to opt out of property filter codegen and runtime checks. Updates source generator, metadata, and runtime logic to honor this flag. Removes UsePropertyFilter constant; emission is now attribute-driven. Also optimizes string serialization for non-ASCII cases and refactors deserializer byte reads for trusted single-segment fast paths. Backward compatible: property filter remains enabled by default.
Optimize AcBinary: add IsTrustedSingleSegment fast-path
Introduce static abstract IsTrustedSingleSegment to IBinaryInputBase and implement in all input types. Update EnsureAvailable to leverage JIT specialization for array-backed inputs, eliminating per-read overhead. Add detailed XML docs on performance trade-offs. No breaking changes; improves deserialization efficiency and clarity.
FastWire: Add markerless string encoding/decoding
Introduced a markerless FastWire path for string properties and collection elements in AcBinary serialization. Strings are now encoded with a 4-byte int32 sentinel header (-1=null, 0=empty, N>0=content) and UTF-16 bytes, eliminating the type code marker in FastWire mode. Updated code generation, runtime, and documentation to support this, while preserving Compact mode behavior and cross-mode compatibility.
Use ReadOnlySequence<byte> in benchmarks for deserialization
Updated all AcBinary and MemoryPack benchmark deserialization and round-trip verification methods to use ReadOnlySequence<byte> overloads instead of byte[] or ToArray(). This ensures benchmarks exercise the production-realistic deserialization path (e.g., for SignalR/Pipe consumers) and aligns buffer writer semantics across serializers. Added comments to clarify intent. No business logic was changed.
Switch to BCL UTF-8 APIs for string (de)serialization
Replaced custom Utf8Transcoder logic with System.Text.Encoding.UTF8 and System.Text.Unicode.Utf8 for string encoding/decoding in AcBinarySerializer and AcBinaryDeserializer. PropertyMetadataBase now uses Encoding.UTF8.GetBytes for property name encoding. Retained Utf8Transcoder for any remaining SIMD/custom logic. No public API changes; internal refactoring for performance and maintainability.
Benchmark stabilization & charset-param workload support
Major overhaul of the custom benchmark harness:
- Per-serializer warmup, GC isolation, pilot discard, and CPU pinning for stable, reproducible results
- Adaptive per-cell iteration targeting (~250ms/sample) and statistical reporting (min/max/stddev/CV)
- CLI/menu support for single-cell A/B runs
- Test data refactored to ASCII baselines with configurable charset suffix (6 presets), selectable via menu; charset recorded in all outputs
- Markdown/console output now includes per-op µs, inter-sample range, CV warnings, and iteration counts
- Documentation updated with rationale, methodology, and notes on reverted/experimental optimizations
Enables reliable, cross-charset, release-grade performance measurement for AcBinary.
- Add overflow/corruption guards to string (de)serialization (writer/reader now throw on invalid lengths)
- Remove dead string serialization methods per BINARY_TODO.md audit
- Update BINARY_TODO.md with closure/resolution for H2Q6, O7G2, V4N5, and related entries
- Add MaxStringCharLength constant and update marker reservations in BinaryTypeCode
- Simplify string cache ASCII verification in deserializer
- Add SGen/Runtime round-trip compatibility tests for large/deep data
- Minor code modernization and style improvements
SIMD Utf8Transcoder.GetUtf8ByteCount + test suite
Introduced SIMD-accelerated Utf8Transcoder.GetUtf8ByteCount for efficient UTF-8 byte counting, replacing all writer-side Encoding.UTF8.GetByteCount usages. Added 29 unit tests for correctness across ASCII, Hungarian, CJK, emoji, and boundary cases. Updated benchmarks to ensure FixStr is bypassed and wire mode is selectable. Documented implementation and dead-code review in BINARY_TODO.md. No public API changes.
Fix Utf8Transcoder AVX2 bug, add SIMD boundary tests
- Added Hungarian language preference rule to copilot-instructions.md.
- Fixed AVX2 SIMD bug in Utf8Transcoder: corrected upper-half store offset from Vector128<ushort>.Count to Vector256<ushort>.Count, preventing memory overlap on 32+ byte ASCII runs.
- Added Utf8TranscoderTests covering all SIMD/scalar paths, with boundary and round-trip tests for ASCII, Hungarian, CJK, emoji, and mixed content, ensuring correctness and BCL compatibility.
Refactor: extract UTF-8 transcoder to Utf8Transcoder
Moved all UTF-8/UTF-16 encoding, decoding, and char counting logic from AcBinarySerializer/AcBinaryDeserializer into a new internal Utf8Transcoder class. Updated all call sites to use the new class. Removed redundant private methods from the original classes. Updated BINARY_TODO.md to clarify SIMD decode status and rationale for deferring AVX2 multi-byte SIMD path. No functional changes—pure refactor for maintainability and future SIMD work.
SIMD UTF-8 upgrades, i18n test data, MVC disabled
- Switch all test/benchmark data to Hungarian UTF-8 strings for i18n coverage
- Add AVX-512BW, Vector256, and Vector128 SIMD paths for UTF-8/UTF-16 encode/decode (ASCII and multi-byte) in binary serializer/deserializer
- Update WireMode docs for encoding guidance per workload/host
- Block-comment and disable MVC formatters and Microsoft.AspNetCore.App reference due to .NET 10 Hybrid client conflict; update docs to reflect temporary state
- Update appsettings: replace WaitForFlush with FlushPolicy
- Revise BINARY_TODO.md for SIMD transcoder progress and next steps
Add docs for AcBinary MVC formatters and pipeline updates
Comprehensive documentation for new ASP.NET Core MVC formatters supporting AcBinary, including registration, media type, request/response flow, error handling, and future plans. Updated project and topic docs to reference MVC formatters and folder structure. Added performance planning entry for StreamPipeWriter congestion fallback. Expanded markerless schema lane rationale and updated architecture docs to reflect MVC formatter integration. Improved navigation and layering documentation.
Remove PipeReader APIs from AcBinaryDeserializer
Refactored to remove all PipeReader-based async deserialization methods from AcBinaryDeserializer. Updated BINARY_TODO.md to clarify that draining PipeReader to AsyncPipeReaderInput is now a consumer responsibility. Refactored AcBinaryInputFormatter to inline the drain-loop and background deserialization, following new layering guidance. Updated comments and docs to reflect these changes.
AcBinary: Add ASCII string markers, doc optimizations
Enhanced string encoding with FixStrAscii/StringAscii markers for efficient ASCII handling, updated header flag base to 0xB0, and expanded documentation with marker-dispatch logic, performance results, and markerless schema lane plans.
AcBinary: ASCII string opt, Type-based API, MVC support
- Add ASCII-optimized string serialization/deserialization with new FixStrAscii/StringAscii markers for fast byte→char widening.
- Introduce non-generic Type-based Serialize/Deserialize overloads for runtime-typed scenarios (plugin, MVC, model binding).
- Add AcBinaryInputFormatter/OutputFormatter and AddAcBinaryFormatters extensions for ASP.NET Core MVC integration.
- Update project references and close ACCORE-BIN-T-N9G6 in docs.
Add issue/TODO for AcBinary default-value omission risk
Documented ACCORE-BIN-I-D9Y2 in BINARY_ISSUES.md, detailing the risk of silent data corruption when omitting default-valued properties if type defaults diverge between writer and reader. Added ACCORE-BIN-T-W7N5 in BINARY_TODO.md to track mitigation options, including a possible opt-out flag and required documentation/tests. Both entries are cross-referenced; decision on mitigation is deferred.
SIMD-accelerated UTF-8 encode/decode for AcBinary
- Added Vector256-based SIMD path for UTF-8 char counting in deserializer, replacing scalar loop for faster ASCII/multibyte handling.
- Introduced EncodeUtf8SinglePass in serializer: layered SIMD/DWORD/scalar UTF-16→UTF-8 encoding, bypassing Encoding.UTF8.GetBytes.
- Updated serializer to use new encoder for string writes.
- Expanded "fastestbyte" benchmark mode to compare both AcBinary (UTF-8/UTF-16) and MemoryPack strategies.
- Improved comments and docs to clarify new SIMD logic.