Skip to content

Commit 7a81c56

Browse files
authored
perf: remove unnecessary lock in ObjectTracker.TrackObjects (#5217)
* perf: remove unnecessary lock in ObjectTracker.TrackObjects TrackedObjects is per-TestContext and TrackObjects is called from a single thread per test context. The lock(kvp.Value) on each HashSet caused Monitor.Enter_Slowpath contention (~1.25% exclusive CPU) during parallel test execution of 1,013+ tests, with no actual concurrent access to protect against. * style: trim comments referencing removed lock
1 parent c3bb360 commit 7a81c56

1 file changed

Lines changed: 5 additions & 7 deletions

File tree

TUnit.Core/Tracking/ObjectTracker.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,15 @@ public void TrackObjects(TestContext testContext)
8585
return;
8686
}
8787

88+
// No lock needed: TrackedObjects is per-TestContext and TrackObjects
89+
// is called from a single thread per test.
8890
foreach (var kvp in trackableDict)
8991
{
90-
lock (kvp.Value)
92+
foreach (var obj in kvp.Value)
9193
{
92-
foreach (var obj in kvp.Value)
94+
if (!alreadyTrackedSnapshot.Contains(obj))
9395
{
94-
if (!alreadyTrackedSnapshot.Contains(obj))
95-
{
96-
TrackObject(obj);
97-
}
96+
TrackObject(obj);
9897
}
9998
}
10099
}
@@ -214,7 +213,6 @@ private async ValueTask UntrackObject(object? obj)
214213
}
215214
}
216215

217-
// Dispose outside the lock to avoid blocking other untrack operations
218216
if (shouldDispose)
219217
{
220218
await disposer.DisposeAsync(obj).ConfigureAwait(false);

0 commit comments

Comments
 (0)