From 6adad363465748a2775a62eb351cc123a755e748 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Sun, 22 Mar 2026 14:11:49 +0000 Subject: [PATCH 1/3] perf: eliminate async state machine in TestCoordinator.ExecuteTestAsync Remove the async/await from TestCoordinator.ExecuteTestAsync, which was a thin wrapper that only awaited TryStartExecutionAsync and discarded the bool result. By checking IsCompletedSuccessfully on the fast path and using a static local function for the async fallback, we eliminate one state machine allocation per test execution in the hot path. --- .../Services/TestExecution/TestCoordinator.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs index c7ea325f1b..b7816c3018 100644 --- a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs +++ b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs @@ -47,10 +47,25 @@ public TestCoordinator( _eventReceiverOrchestrator = eventReceiverOrchestrator; } - public async ValueTask ExecuteTestAsync(AbstractExecutableTest test, CancellationToken cancellationToken) + public ValueTask ExecuteTestAsync(AbstractExecutableTest test, CancellationToken cancellationToken) { - await _executionGuard.TryStartExecutionAsync(test.TestId, + var task = _executionGuard.TryStartExecutionAsync(test.TestId, () => ExecuteTestInternalAsync(test, cancellationToken)); + + // Avoid async state machine by handling the common synchronous completion path + if (task.IsCompletedSuccessfully) + { + // Consume the result to observe any exceptions + _ = task.Result; + return default; + } + + return AwaitAndDiscard(task); + + static async ValueTask AwaitAndDiscard(ValueTask t) + { + await t.ConfigureAwait(false); + } } private async ValueTask ExecuteTestInternalAsync(AbstractExecutableTest test, CancellationToken cancellationToken) From 8b3333601d30bfba3c2d86e88ad4539b0399678d Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Sun, 22 Mar 2026 14:13:21 +0000 Subject: [PATCH 2/3] style: remove redundant Result access on successful ValueTask --- TUnit.Engine/Services/TestExecution/TestCoordinator.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs index b7816c3018..8a3c81005e 100644 --- a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs +++ b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs @@ -52,11 +52,9 @@ public ValueTask ExecuteTestAsync(AbstractExecutableTest test, CancellationToken var task = _executionGuard.TryStartExecutionAsync(test.TestId, () => ExecuteTestInternalAsync(test, cancellationToken)); - // Avoid async state machine by handling the common synchronous completion path + // Fast path: avoid async state machine when the task completed synchronously if (task.IsCompletedSuccessfully) { - // Consume the result to observe any exceptions - _ = task.Result; return default; } From f1435c4b8763e2bdf410e8777202090e2653f9fe Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Sun, 22 Mar 2026 14:21:15 +0000 Subject: [PATCH 3/3] refactor: change TryStartExecutionAsync to return ValueTask, eliminating state machine in ExecuteTestAsync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bool return from TryStartExecutionAsync was never used by any caller. By returning ValueTask instead of ValueTask, ExecuteTestAsync becomes a pure one-liner that directly returns the ValueTask — no async state machine, no IsCompletedSuccessfully check, and no AwaitAndDiscard helper needed. --- .../Services/TestExecution/TestCoordinator.cs | 17 +---------------- .../TestExecution/TestExecutionGuard.cs | 12 +++++------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs index 8a3c81005e..29e444588b 100644 --- a/TUnit.Engine/Services/TestExecution/TestCoordinator.cs +++ b/TUnit.Engine/Services/TestExecution/TestCoordinator.cs @@ -48,24 +48,9 @@ public TestCoordinator( } public ValueTask ExecuteTestAsync(AbstractExecutableTest test, CancellationToken cancellationToken) - { - var task = _executionGuard.TryStartExecutionAsync(test.TestId, + => _executionGuard.TryStartExecutionAsync(test.TestId, () => ExecuteTestInternalAsync(test, cancellationToken)); - // Fast path: avoid async state machine when the task completed synchronously - if (task.IsCompletedSuccessfully) - { - return default; - } - - return AwaitAndDiscard(task); - - static async ValueTask AwaitAndDiscard(ValueTask t) - { - await t.ConfigureAwait(false); - } - } - private async ValueTask ExecuteTestInternalAsync(AbstractExecutableTest test, CancellationToken cancellationToken) { try diff --git a/TUnit.Engine/Services/TestExecution/TestExecutionGuard.cs b/TUnit.Engine/Services/TestExecution/TestExecutionGuard.cs index 06ac0c688c..32fdc49a77 100644 --- a/TUnit.Engine/Services/TestExecution/TestExecutionGuard.cs +++ b/TUnit.Engine/Services/TestExecution/TestExecutionGuard.cs @@ -10,12 +10,12 @@ internal sealed class TestExecutionGuard { private readonly ConcurrentDictionary> _executingTests = new(); - public ValueTask TryStartExecutionAsync(string testId, Func executionFunc) + public ValueTask TryStartExecutionAsync(string testId, Func executionFunc) { // Fast path: check if test is already executing without allocating a TCS if (_executingTests.TryGetValue(testId, out var existingTcs)) { - return new ValueTask(WaitForExistingExecutionAsync(existingTcs)); + return new ValueTask(WaitForExistingExecutionAsync(existingTcs)); } var tcs = new TaskCompletionSource(); @@ -23,25 +23,23 @@ public ValueTask TryStartExecutionAsync(string testId, Func exe if (existingTcs != tcs) { - return new ValueTask(WaitForExistingExecutionAsync(existingTcs)); + return new ValueTask(WaitForExistingExecutionAsync(existingTcs)); } return ExecuteAndCompleteAsync(testId, tcs, executionFunc); } - private static async Task WaitForExistingExecutionAsync(TaskCompletionSource tcs) + private static async Task WaitForExistingExecutionAsync(TaskCompletionSource tcs) { await tcs.Task.ConfigureAwait(false); - return false; } - private async ValueTask ExecuteAndCompleteAsync(string testId, TaskCompletionSource tcs, Func executionFunc) + private async ValueTask ExecuteAndCompleteAsync(string testId, TaskCompletionSource tcs, Func executionFunc) { try { await executionFunc().ConfigureAwait(false); tcs.SetResult(true); - return true; } catch (Exception ex) {