[efficiency-improver] perf: single-pass TestNode property serialization in SerializerUtilities#8806
Conversation
Eliminate a redundant enumeration of TestNode.Properties during JSON-RPC serialization. Previously, Properties was traversed twice: 1. OfType<TestMetadataProperty>() to collect trait metadata 2. A foreach loop to process all other properties Now a single foreach handles all property types, collecting TestMetadataProperty items into a lazy-allocated list/JsonArray that is assigned to 'traits' after the loop. This removes one full Properties scan per TestNode sent over the server-mode JSON-RPC channel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR targets the JSON-RPC server-mode serialization path for TestNode by reducing work performed while serializing TestNode.Properties in SerializerUtilities, aiming to lower allocations and CPU usage.
Changes:
- Refactors
TestNodeserialization inSerializerUtilitiesto collectTestMetadataProperty(“traits”) during the mainforeachovern.Properties(single pass). - Lazily allocates the traits container (
List<KeyValuePair<string,string>>on NETCOREAPP,JsonArrayon non-NETCOREAPP) only when traits are present.
Show a summary per file
| File | Description |
|---|---|
| src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs | Converts TestNode.Properties trait handling to a single-pass collection with lazy allocation. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 2
- SerializerUtilities: Reserve raits slot up-front so the serialized JSON keeps the original wire format (traits right after display-name). Fixes FormatterUtilitiesTests on the !NETCOREAPP path (Jsonite). - SerializerUtilities: Unify the node-type fallback under the !ContainsKey guard for both NETCOREAPP and !NETCOREAPP, avoiding a latent ArgumentException when a TestNodeStateProperty was present. - Json.cs: Apply the same single-pass TestMetadataProperty collection used in SerializerUtilities; Insert the traits entry at index 2 after the loop to preserve key ordering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed the review feedback and fixed the failing build: Build failure (net462 only) in Review comment 1 (NETCOREAPP Review comment 2 (apply same change to All 1059 tests pass on net9.0 and all 1050 tests pass on net462 locally. |
🤖 Efficiency Improver — automated AI assistant focused on reducing the energy consumption and computational footprint of this repository.
Goal and Rationale
Eliminate a redundant enumeration of
TestNode.Propertiesduring JSON-RPC serialization. This is the server-mode hot path — called for everyTestNodepushed from the test host to IDEs (VS, VS Code, Rider) over the JSON-RPC channel.Focus Area
Code-Level Efficiency — unnecessary object allocation and CPU work per test result.
Approach
Previously,
Propertieswas traversed twice perTestNode:n.Properties.OfType<TestMetadataProperty>()— allocates an intermediate array to collect trait metadataforeachloop over all properties to handle all other typesNow a single
foreachhandles all property types.TestMetadataPropertyitems are collected into a lazy-allocatedList<KVP>(NETCOREAPP) orJsonArray(netfx), assigned to"traits"after the loop.Energy Efficiency Evidence
Proxy metric: heap allocation count and CPU instructions.
Propertiesscan + 1 intermediateTestMetadataProperty[]allocation perTestNodeserialized??=)For a typical IDE session with 1 000 tests, this eliminates ≥1 000 unnecessary array allocations and 1 000 extra
PropertyBagtraversals during serialization, reducing GC pressure and CPU cycles in the JSON-RPC hot path.GSF — Hardware Efficiency: fewer allocations → less GC work → better utilization of the CPU and DRAM already in use.
Trade-offs
"traits"may differ from the previous order (traits appear after other properties rather than near the top). JSON-RPC consumers must not depend on key ordering (the spec does not guarantee it).#if NETCOREAPPbranching, but the logic is straightforward.Reproducibility
./build.sh # verify build successTest Status
✅ Build succeeded (0 errors, 0 warnings)
Add this agentic workflows to your repo
To install this agentic workflow, run