From 44be408fdc74cc4e925f18fadf7c81242730912f Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Thu, 28 May 2026 18:16:32 +0100 Subject: [PATCH 1/2] perf(engine): replace Select+ToArray with manual Type[] build (#6043) Drops the iterator + delegate allocations from per-test-registration parameter-type extraction in TestRegistry and TestGenericTypeResolver. --- TUnit.Engine/Services/TestGenericTypeResolver.cs | 9 ++++++++- TUnit.Engine/Services/TestRegistry.cs | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/TUnit.Engine/Services/TestGenericTypeResolver.cs b/TUnit.Engine/Services/TestGenericTypeResolver.cs index f6a5e216dc..294f3440da 100644 --- a/TUnit.Engine/Services/TestGenericTypeResolver.cs +++ b/TUnit.Engine/Services/TestGenericTypeResolver.cs @@ -44,11 +44,18 @@ public static TestGenericTypeResolution Resolve(TestMetadata metadata, TestBuild // Otherwise resolve from GenericMethodInfo if the test method is a generic definition else if (metadata.GenericMethodInfo != null) { + var parameters = metadata.MethodMetadata.Parameters; + var parameterTypes = new Type[parameters.Length]; + for (var i = 0; i < parameters.Length; i++) + { + parameterTypes[i] = parameters[i].Type; + } + result.ResolvedMethodGenericArguments = ResolveMethodGenericArguments( metadata.MethodMetadata, metadata.GenericMethodInfo, testData.MethodData, - metadata.MethodMetadata.Parameters.Select(p => p.Type).ToArray()); + parameterTypes); } return result; diff --git a/TUnit.Engine/Services/TestRegistry.cs b/TUnit.Engine/Services/TestRegistry.cs index f6e3984684..851598c9bd 100644 --- a/TUnit.Engine/Services/TestRegistry.cs +++ b/TUnit.Engine/Services/TestRegistry.cs @@ -138,7 +138,13 @@ public async Task CreateTestVariant( nameof(methodArguments)); } - var parameterTypes = methodMetadata.Parameters.Select(p => p.Type).ToArray(); + var parameters = methodMetadata.Parameters; + var parameterTypes = new Type[parameters.Length]; + for (var i = 0; i < parameters.Length; i++) + { + parameterTypes[i] = parameters[i].Type; + } + var methodInfo = methodMetadata.Type.GetMethod( methodMetadata.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, From a4b92f3d557aac12a17e8399c633efad1c680911 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Thu, 28 May 2026 18:57:09 +0100 Subject: [PATCH 2/2] refactor: use Array.ConvertAll for parameter type extraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review feedback on #6076 — collapse the manual loop to a single Array.ConvertAll call (same allocation profile, established repo pattern via GenericTypeHelper). --- TUnit.Engine/Services/TestGenericTypeResolver.cs | 7 +------ TUnit.Engine/Services/TestRegistry.cs | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/TUnit.Engine/Services/TestGenericTypeResolver.cs b/TUnit.Engine/Services/TestGenericTypeResolver.cs index 294f3440da..358c2e5dce 100644 --- a/TUnit.Engine/Services/TestGenericTypeResolver.cs +++ b/TUnit.Engine/Services/TestGenericTypeResolver.cs @@ -44,12 +44,7 @@ public static TestGenericTypeResolution Resolve(TestMetadata metadata, TestBuild // Otherwise resolve from GenericMethodInfo if the test method is a generic definition else if (metadata.GenericMethodInfo != null) { - var parameters = metadata.MethodMetadata.Parameters; - var parameterTypes = new Type[parameters.Length]; - for (var i = 0; i < parameters.Length; i++) - { - parameterTypes[i] = parameters[i].Type; - } + var parameterTypes = Array.ConvertAll(metadata.MethodMetadata.Parameters, p => p.Type); result.ResolvedMethodGenericArguments = ResolveMethodGenericArguments( metadata.MethodMetadata, diff --git a/TUnit.Engine/Services/TestRegistry.cs b/TUnit.Engine/Services/TestRegistry.cs index 851598c9bd..de91c8a71c 100644 --- a/TUnit.Engine/Services/TestRegistry.cs +++ b/TUnit.Engine/Services/TestRegistry.cs @@ -138,12 +138,7 @@ public async Task CreateTestVariant( nameof(methodArguments)); } - var parameters = methodMetadata.Parameters; - var parameterTypes = new Type[parameters.Length]; - for (var i = 0; i < parameters.Length; i++) - { - parameterTypes[i] = parameters[i].Type; - } + var parameterTypes = Array.ConvertAll(methodMetadata.Parameters, p => p.Type); var methodInfo = methodMetadata.Type.GetMethod( methodMetadata.Name,