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
[PR #aw_pr_new open] Avoid List<TestResult> allocation in RunTestMethodAsync non-data-driven fast path — single combined attribute scan replaces 2 separate scans; ~3 heap allocations saved per non-data-driven test
AntiTerminal.StopUpdate() — _stringBuilder.ToString() allocates on every terminal-output flush; blocked on IConsole interface limitation (netstandard2.0 target). Low priority.
SilenceDrivenHeartbeatRenderer — allocations only on rare heartbeat/slow-test paths; not a hot path. Low priority.
ClassifyOutcome in TestResultCaptureHelper.cs — add explicit CancelledTestNodeStateProperty arm to avoid Array.IndexOf fallback for obsolete type. Very low priority.
Discovered Commands
# Build all projects (Debug)
./build.sh
# Build + run unit tests
./build.sh -test
# Pack NuGet packages (required before acceptance tests and performance runner)
./build.sh -pack
# Run acceptance integration tests (requires -pack first)
./build.sh -pack -test -integrationTest
# Run performance timing scenarios (requires -pack first)
.dotnet/dotnet run --project test/Performance/MSTest.Performance.Runner \
-- execute --pipelineNameFilter "*PlainProcess*"# Run a single test project (using installed SDK in .dotnet/)
.dotnet/dotnet run --project <project-path> -f net9.0 --no-build -- --treenode-filter "*/*/MyTestClass/*"
🔍 Task 2/3: Identified RunTestMethodAsync allocates List<TestResult> + spread array for every non-data-driven test (common case), plus performs 2 redundant attribute scans
🔧 Task 3: Submitted PR #aw_pr_new on branch perf-assist/skip-list-alloc-non-data-driven — avoid List<TestResult> allocation and 2-scan cost in non-data-driven fast path; ~3 heap allocations saved per test
🔍 Task 2/3: Identified CaptureLifecycleProperties unconditionally allocates two objects (Dictionary + ReadOnlyDictionary) even when no user properties were set — the common case
🔍 Identified per-test Queue/Stack allocation as next target
🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Perf Improver workflow. · 1.7K AIC · ⌖ 26.2 AIC · ⊞ 57.7K · [◷]( · ◷)
Add this agentic workflows to your repo
To install this agentic workflow, run
gh aw add githubnext/agentics/workflows/perf-improver.md@main
Activity for June 2026
Suggested Actions for Maintainer
dotnet testserver-mode scenario to performance runner — ReviewList<TestResult>allocation inRunTestMethodAsyncnon-data-driven fast path — ReviewPerformance Opportunities Backlog
Queue/Stackallocation in MSTest adapter lifecycleArray.IndexOf(GetType())withispattern matching inTestApplicationResult,AbortForMaxFailedTestsExtension,RetryDataConsumerTestNodeUidallocation inPopulateTestNodeStatistics#9348 merged] Avoid redundantTestNodeUidallocation inPerRequestServerDataConsumer.PopulateTestNodeStatistics(server mode, 2×N per test run)TestContextImplementationallocations inUnitTestRunner.RunSingleTestAsync: for tests 2+ in an assembly/class, ~2 dictionary copies + 2CancellationTokenRegistrationallocs skipped per testTestContextImplementationallocation to last test only — saves C×(K−1) allocations for C classes averaging K tests eachDictionary+ReadOnlyDictionaryallocation inCaptureLifecyclePropertieswhen init method sets no properties (common case); also skipMergePropertieslock acquisition per testDotnetTestProcessstep +Scenario1_DotnetTest_PlainProcesspipeline to measure MTP server-mode (JSON-RPC / named-pipe) timing; auto-captured by existing*PlainProcess*nightly filter (addresses [efficiency-improver] Add server-mode (JSON-RPC) performance scenario to nightly perf pipeline #9480)List<TestResult>allocation inRunTestMethodAsyncnon-data-driven fast path — single combined attribute scan replaces 2 separate scans; ~3 heap allocations saved per non-data-driven testAntiTerminal.StopUpdate()—_stringBuilder.ToString()allocates on every terminal-output flush; blocked onIConsoleinterface limitation (netstandard2.0 target). Low priority.SilenceDrivenHeartbeatRenderer— allocations only on rare heartbeat/slow-test paths; not a hot path. Low priority.ClassifyOutcomeinTestResultCaptureHelper.cs— add explicitCancelledTestNodeStatePropertyarm to avoidArray.IndexOffallback for obsolete type. Very low priority.Discovered Commands
Run History
2026-06-29 15:00 UTC - Run
RunTestMethodAsyncallocatesList<TestResult>+ spread array for every non-data-driven test (common case), plus performs 2 redundant attribute scansperf-assist/skip-list-alloc-non-data-driven— avoidList<TestResult>allocation and 2-scan cost in non-data-driven fast path; ~3 heap allocations saved per test2026-06-28 14:19 UTC - Run
perf-assist/dotnet-test-server-mode-scenario— addDotnetTestProcessstep andScenario1_DotnetTest_PlainProcesspipeline to measure MTP server-mode (JSON-RPC / named-pipe) timing; auto-captured by existing*PlainProcess*nightly filter (addresses [efficiency-improver] Add server-mode (JSON-RPC) performance scenario to nightly perf pipeline #9480)2026-06-27 UTC - Run
CaptureLifecyclePropertiesunconditionally allocates two objects (Dictionary + ReadOnlyDictionary) even when no user properties were set — the common caseperf-assist/avoid-empty-snapshot-alloc— skip allocations inCaptureLifecyclePropertieswhen no non-label properties exist; null return avoids lock acquisition per test inMergeProperties2026-06-26 15:00 UTC - Run
UnitTestRunner.cshot paths — foundtestContextForClassCleanupallocated unconditionally for every test even when not usedperf-assist/defer-class-cleanup-context-alloc2026-06-25 14:30 UTC - Run
2026-06-24 14:17 UTC - Run
2026-06-23 UTC - Run
TestNodeUidallocation inPopulateTestNodeStatistics#9348 merged by Evangelink on 2026-06-232026-06-19 UTC - Run
TestNodeUidallocation inPopulateTestNodeStatistics#9348: Avoid redundantTestNodeUidallocation — MERGED 2026-06-232026-06-21 14:14 UTC - Run
2026-06-20 14:30 UTC - Run
Array.IndexOf(GetType())withispattern matching — MERGED 2026-06-222026-06-17 - Run
2026-06-15 - Run
Add this agentic workflows to your repo
To install this agentic workflow, run