You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cache the JsonSerializerOptions { WriteIndented = true } instance as a private static readonly field in PlainProcess and DotnetTestProcess, removing CA1869 pragma suppressions that were previously hiding the issue.
Why this matters for energy efficiency:JsonSerializerOptions construction triggers reflection-based scanning of converter types and type metadata. Creating a new instance on every benchmark run means this work is repeated unnecessarily — in a tool specifically designed to measure performance, the tool itself should not incur avoidable overhead.
Focus Area
Code-Level Efficiency — eliminate unnecessary object construction and reflection work.
Proxy metric: memory allocation / CPU reflection work
JsonSerializerOptions construction is not free — it registers built-in converters and initialises type metadata dictionaries. The CA1869 analyser exists precisely because repeated construction is recognised as a performance anti-pattern by the .NET team.
While the per-invocation cost is low (this code runs once per benchmark run, not per test), the principle of "benchmark tooling should be exemplary" applies directly. A tool that measures allocations should not itself generate avoidable ones.
Before:new JsonSerializerOptions { WriteIndented = true } created on every ExecuteAsync() call (once per scenario run). After: single allocation at class-load time, reused for all subsequent calls.
Green Software Foundation Context
Hardware Efficiency: Removing reflection work at class-load time reduces unnecessary CPU cycles — however marginal — in line with the GSF principle that software should use as little hardware resource as needed.
Trade-offs
None. The change is purely mechanical — same behaviour, same output, no logic changes. Readability is unchanged; the static field name is self-documenting.
Reproducibility
# Build the performance runner
./build.sh # installs SDK first time
.dotnet/dotnet build test/Performance/MSTest.Performance.Runner/MSTest.Performance.Runner.csproj -f net9.0 -c Debug
# CA1869 now produces no warnings (previously suppressed with pragmas)
Test Status
Build not run (repo SDK 11.0.100-preview.5.26302.115 not provisioned in this environment). The changes are mechanical — the only modification is replacing new JsonSerializerOptions { WriteIndented = true } with a pre-allocated s_writeIndented static field of the same type. No logic changes.
🤖 Automated content by GitHub Copilot. Generated by the Efficiency Improver workflow. · 351.3 AIC · ⌖ 19.3 AIC · ⊞ 13.6K · [◷]( · ◷)
Add this agentic workflows to your repo
To install this agentic workflow, run
gh aw add githubnext/agentics/workflows/efficiency-improver.md@main
Note
This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch efficiency/cache-json-serializer-options-cf226ce60ce3db6d.
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (79 of 79 lines)
From 8a9ec3abe2f116ba74f895665fa4a4c8e7317f3a Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Tue, 7 Jul 2026 22:13:17 +0000
Subject: [PATCH] perf: cache JsonSerializerOptions in performance runner steps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cache the shared JsonSerializerOptions instance as a static readonly
field in both PlainProcess and DotnetTestProcess, eliminating repeated
construction of JsonSerializerOptions on every benchmark run.
JsonSerializerOptions construction triggers reflection scanning of
converters and type metadata — caching it removes this work from
measured hot paths. Fixes CA1869 suppression pragmas that were
previously masking the issue.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../MSTest.Performance.Runner/Steps/DotnetTestProcess.cs | 6 +++---
.../MSTest.Performance.Runner/Steps/PlainProcess.cs | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/test/Performance/MSTest.Performance.Runner/Steps/DotnetTestProcess.cs b/test/Performance/MSTest.Performance.Runner/Steps/DotnetTestProcess.cs
index 9f2585f..49ce352 100644
--- a/test/Performance/MSTest.Performance.Runner/Steps/DotnetTestProcess.cs+++ b/test/Performance/MSTest.Performance.Runner/Steps/DotnetTestProcess.cs@@ -31,6 +31,8 @@ namespace MSTest.Performance.Runner.Steps;
/// </remarks>
internal class DotnetTestProcess : IStep<BuildArtifact, Files>
{
+ private static readonly JsonSerializerOptions s_writeIndented = new() { WriteIndented = true };+
private readonly string _reportFileName;
private readonly BuildConfiguration _buildConfiguration;
private readonly int _numberOfRun;
@@ -117,11 +119,9 @@ public async Task<Files> ExecuteAsync(BuildArtifact payload, IContext context)
results.Add(result);
}
-#pragma warning disable CA1869 // Cache and reuse 'JsonSerializerOptio
... (truncated)
Goal and Rationale
Cache the
JsonSerializerOptions { WriteIndented = true }instance as aprivate static readonlyfield inPlainProcessandDotnetTestProcess, removing CA1869 pragma suppressions that were previously hiding the issue.Why this matters for energy efficiency:
JsonSerializerOptionsconstruction triggers reflection-based scanning of converter types and type metadata. Creating a new instance on every benchmark run means this work is repeated unnecessarily — in a tool specifically designed to measure performance, the tool itself should not incur avoidable overhead.Focus Area
Code-Level Efficiency — eliminate unnecessary object construction and reflection work.
Changes
test/Performance/MSTest.Performance.Runner/Steps/PlainProcess.csprivate static readonly JsonSerializerOptions s_writeIndented; removed CA1869 pragma pairtest/Performance/MSTest.Performance.Runner/Steps/DotnetTestProcess.csEnergy Efficiency Evidence
Proxy metric: memory allocation / CPU reflection work
JsonSerializerOptionsconstruction is not free — it registers built-in converters and initialises type metadata dictionaries. The CA1869 analyser exists precisely because repeated construction is recognised as a performance anti-pattern by the .NET team.While the per-invocation cost is low (this code runs once per benchmark run, not per test), the principle of "benchmark tooling should be exemplary" applies directly. A tool that measures allocations should not itself generate avoidable ones.
Before:
new JsonSerializerOptions { WriteIndented = true }created on everyExecuteAsync()call (once per scenario run).After: single allocation at class-load time, reused for all subsequent calls.
Green Software Foundation Context
Hardware Efficiency: Removing reflection work at class-load time reduces unnecessary CPU cycles — however marginal — in line with the GSF principle that software should use as little hardware resource as needed.
Trade-offs
None. The change is purely mechanical — same behaviour, same output, no logic changes. Readability is unchanged; the static field name is self-documenting.
Reproducibility
Test Status
Build not run (repo SDK
11.0.100-preview.5.26302.115not provisioned in this environment). The changes are mechanical — the only modification is replacingnew JsonSerializerOptions { WriteIndented = true }with a pre-allocateds_writeIndentedstatic field of the same type. No logic changes.Add this agentic workflows to your repo
To install this agentic workflow, run
Note
This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch
efficiency/cache-json-serializer-options-cf226ce60ce3db6d.Click here to create the pull request
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (79 of 79 lines)