Skip to content

Commit 648d2b6

Browse files
perf: skip Enumerator, Hashset and state machine (#4225)
1 parent 9a9e0e2 commit 648d2b6

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

TUnit.Core/Tracking/ObjectTracker.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Concurrent;
2+
using System.Collections.Immutable;
23
using System.Diagnostics.CodeAnalysis;
34
using TUnit.Core.Helpers;
45

@@ -48,12 +49,17 @@ private static Counter GetOrCreateCounter(object obj) =>
4849
s_trackedObjects.GetOrAdd(obj, static _ => new Counter());
4950

5051
/// <summary>
51-
/// Flattens a ConcurrentDictionary of depth-keyed HashSets into a single HashSet.
52+
/// Flattens a ConcurrentDictionary of depth-keyed HashSets into a single ISet.
5253
/// Thread-safe: locks each HashSet while copying.
5354
/// Pre-calculates capacity to avoid HashSet resizing during population.
5455
/// </summary>
55-
private static HashSet<object> FlattenTrackedObjects(ConcurrentDictionary<int, HashSet<object>> trackedObjects)
56+
private static ISet<object> FlattenTrackedObjects(ConcurrentDictionary<int, HashSet<object>> trackedObjects)
5657
{
58+
if (trackedObjects.IsEmpty)
59+
{
60+
return ImmutableHashSet<object>.Empty;
61+
}
62+
5763
#if NETSTANDARD2_0
5864
// .NET Standard 2.0 doesn't support HashSet capacity constructor
5965
var result = new HashSet<object>(Helpers.ReferenceEqualityComparer.Instance);
@@ -91,8 +97,13 @@ public void TrackObjects(TestContext testContext)
9197
var alreadyTracked = FlattenTrackedObjects(testContext.TrackedObjects);
9298

9399
// Get new trackable objects
94-
var newTrackableObjects = new HashSet<object>(Helpers.ReferenceEqualityComparer.Instance);
95100
var trackableDict = trackableObjectGraphProvider.GetTrackableObjects(testContext);
101+
if (trackableDict.IsEmpty && alreadyTracked.Count == 0)
102+
{
103+
return;
104+
}
105+
106+
var newTrackableObjects = new HashSet<object>(Helpers.ReferenceEqualityComparer.Instance);
96107
foreach (var kvp in trackableDict)
97108
{
98109
lock (kvp.Value)
@@ -113,11 +124,20 @@ public void TrackObjects(TestContext testContext)
113124
}
114125
}
115126

116-
public async ValueTask UntrackObjects(TestContext testContext, List<Exception> cleanupExceptions)
127+
public ValueTask UntrackObjects(TestContext testContext, List<Exception> cleanupExceptions)
117128
{
118129
// Get all objects to untrack (DRY: use helper method)
119130
var objectsToUntrack = FlattenTrackedObjects(testContext.TrackedObjects);
131+
if (objectsToUntrack.Count == 0)
132+
{
133+
return ValueTask.CompletedTask;
134+
}
120135

136+
return UntrackObjectsAsync(cleanupExceptions, objectsToUntrack);
137+
}
138+
139+
private async ValueTask UntrackObjectsAsync(List<Exception> cleanupExceptions, ISet<object> objectsToUntrack)
140+
{
121141
foreach (var obj in objectsToUntrack)
122142
{
123143
try

0 commit comments

Comments
 (0)