-
Notifications
You must be signed in to change notification settings - Fork 723
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4034 from lahma/test-case-perf-improvements-v3
Improve method discovery and filtering performance
- Loading branch information
Showing
28 changed files
with
516 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
src/NUnitFramework/framework/Internal/Builders/MethodInfoCache.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt | ||
|
||
using System.Collections.Concurrent; | ||
using System.Collections.Generic; | ||
using NUnit.Framework.Interfaces; | ||
|
||
namespace NUnit.Framework.Internal.Builders | ||
{ | ||
/// <summary> | ||
/// Caches static information for IMethodInfo to reduce re-calculations and memory allocations from reflection. | ||
/// </summary> | ||
internal static class MethodInfoCache | ||
{ | ||
// we would otherwise do a lot of attribute allocations when repeatedly checking the same method for example | ||
// in case of building TestCaseAttribute-based tests | ||
#if NET35 | ||
private static readonly Dictionary<IMethodInfo, TestMethodMetadata> MethodMetadataCache = new Dictionary<IMethodInfo, TestMethodMetadata>(); | ||
#else | ||
private static readonly ConcurrentDictionary<IMethodInfo, TestMethodMetadata> MethodMetadataCache = new ConcurrentDictionary<IMethodInfo, TestMethodMetadata>(); | ||
#endif | ||
|
||
/// <summary> | ||
/// Returns cached metadata for method instance. | ||
/// </summary> | ||
internal static TestMethodMetadata Get(IMethodInfo method) | ||
{ | ||
#if NET35 | ||
lock (MethodMetadataCache) | ||
{ | ||
if (!MethodMetadataCache.TryGetValue(method, out var metadata)) | ||
MethodMetadataCache.Add(method, metadata = new TestMethodMetadata(method)); | ||
|
||
return metadata; | ||
} | ||
#else | ||
return MethodMetadataCache.GetOrAdd(method, m => new TestMethodMetadata(m)); | ||
#endif | ||
} | ||
|
||
/// <summary> | ||
/// Memoization of TestMethod information to reduce subsequent allocations from parameter and attribute information. | ||
/// </summary> | ||
internal sealed class TestMethodMetadata | ||
{ | ||
public TestMethodMetadata(IMethodInfo method) | ||
{ | ||
Parameters = method.GetParameters(); | ||
IsAsyncOperation = AsyncToSyncAdapter.IsAsyncOperation(method.MethodInfo); | ||
IsVoidOrUnit = Reflect.IsVoidOrUnit(method.ReturnType.Type); | ||
|
||
// TODO could probably go trough inherited and non inherited in two passes instead of multiple | ||
|
||
// inherited | ||
RepeatTestAttributes = method.GetCustomAttributes<IRepeatTest>(true); | ||
WrapTestMethodAttributes = method.GetCustomAttributes<IWrapTestMethod>(true); | ||
WrapSetupTearDownAttributes = method.GetCustomAttributes<IWrapSetUpTearDown>(true); | ||
ApplyToContextAttributes = method.GetCustomAttributes<IApplyToContext>(true); | ||
|
||
// non-inherited | ||
TestBuilderAttributes = method.GetCustomAttributes<ITestBuilder>(false); | ||
TestActionAttributes = method.GetCustomAttributes<ITestAction>(false); | ||
} | ||
|
||
public IParameterInfo[] Parameters { get; } | ||
public bool IsAsyncOperation { get; } | ||
public bool IsVoidOrUnit { get; } | ||
|
||
public IRepeatTest[] RepeatTestAttributes { get; } | ||
public ITestBuilder[] TestBuilderAttributes { get; } | ||
public IWrapTestMethod[] WrapTestMethodAttributes { get; } | ||
public ITestAction[] TestActionAttributes { get; } | ||
public IWrapSetUpTearDown[] WrapSetupTearDownAttributes { get; } | ||
public IApplyToContext[] ApplyToContextAttributes { get; } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.