Skip to content

[efficiency-improver] perf: avoid redundant GetParameters() allocations in test-invocation hot path #9647

Description

@github-actions

Summary

MethodInfo.GetParameters() is a CLR-guaranteed allocation: it always returns a freshly allocated ParameterInfo[] for safety (even for repeated calls on the same method). TestMethodInfo already caches this result in the ParameterTypes property (added in PR #9514), but GetInvokeResultAsync never sees that cache — it receives only the raw MethodInfo and therefore re-calls GetParameters() on every single test invocation.

For generic test methods the situation is worse: GetParameters() was called twice per invocation — once at the top of GetInvokeResultAsync and once inside ConstructGenericMethod.

Changes

Branch: efficiency/pass-cached-params-to-invoke (1 commit: 0bc0bb6)

src/Adapter/MSTestAdapter.PlatformServices/Extensions/MethodInfoExtensions.cs   | +37 / -12
src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodInfo.Execution.cs|  +2 /  -2

MethodInfoExtensions.cs

  • Added hot-path overload GetInvokeResultAsync(MethodInfo, object?, object?[]?, ParameterInfo[]) that accepts pre-cached parameters.
  • Extracted private GetInvokeResultAsyncCore(...) so both overloads share one implementation (DRY, no behaviour change).
  • ConstructGenericMethod now accepts ParameterInfo[] cachedParameters instead of calling methodInfo.GetParameters() internally — eliminates the double-allocation for generic tests.

TestMethodInfo.Execution.cs

  • Both hot-path call sites (lines 147 and 164) updated to pass ParameterTypes (the already-cached property) to the new overload.

Energy Efficiency Evidence

Proxy metric: heap allocation / GC pressure (maps to energy via: fewer short-lived allocations → fewer GC collections → fewer CPU stalls due to GC → less energy drawn from DRAM and CPU during GC sweeps).

Scenario Before After
Plain test (non-generic, non-data-driven) 1 ParameterInfo[] alloc per call 0 allocations (served from cache)
Data-driven test, N rows, non-generic N ParameterInfo[] allocs per run 0 allocations
Data-driven test, N rows, generic method 2N ParameterInfo[] allocs per run 0 allocations

For a typical parameterized suite with 1000 data rows, this removes ~1000+ unnecessary short-lived heap allocations per test run.

GSF Principle: Hardware Efficiency — reducing GC frequency makes better use of the CPU and DRAM that are physically powering the test host.

Relationship to existing work

Validation

The SDK required to build locally is .NET 11.0.100-preview (Arcade-provisioned via ./build.sh). CI will run the full test suite on PR open.

To review: main...efficiency/pass-cached-params-to-invoke

🤖 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 Efficiency Improver workflow. · 400.5 AIC · ⌖ 11.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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/performanceRuntime / build performance / efficiency.type/automationCreated or maintained by an agentic workflow.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions