Soenneker.Reflection.Cache
2.1.144
Prefix Reserved
See the version list below for details.
dotnet add package Soenneker.Reflection.Cache --version 2.1.144
NuGet\Install-Package Soenneker.Reflection.Cache -Version 2.1.144
<PackageReference Include="Soenneker.Reflection.Cache" Version="2.1.144" />
paket add Soenneker.Reflection.Cache --version 2.1.144
#r "nuget: Soenneker.Reflection.Cache, 2.1.144"
// Install Soenneker.Reflection.Cache as a Cake Addin #addin nuget:?package=Soenneker.Reflection.Cache&version=2.1.144 // Install Soenneker.Reflection.Cache as a Cake Tool #tool nuget:?package=Soenneker.Reflection.Cache&version=2.1.144
Soenneker.Reflection.Cache
The fastest .NET Reflection cache
Why?
System.Reflection is slow. If you need to call Reflection code repeatedly, this library can drastically speed up subsequent calls. It's thread-safe and supports concurrency.
Installation
dotnet add package Soenneker.Reflection.Cache
This cache can either be added to DI like so:
public void ConfigureServices(IServiceCollection services)
{
services.AddReflectionCacheAsSingleton(); // or AddReflectionCacheAsScoped()
}
and you could access it like:
public class MyService
{
private readonly IReflectionCache _cache;
public MyService(IReflectionCache cache)
{
_cache = cache;
}
}
or you can instantiate it manually:
var cache = new ReflectionCache(threadSafe: true); // can be disabled for extra speed
Usage
var type1 = Type.GetType("System.String"); // <-- regular Reflection
var type2 = cache.GetType("System.String"); // <-- cached Reflection
bool areEqual = type1 == type2; // true
Keep in mind:
cache.GetType("System.String"); // <-- as slow as regular Reflection
cache.GetType("System.String"); // <-- very fast because the first call was cached
⚠️ Important ⚠️
Be mindful of the "cache chain". Use the Cached
methods and types until you need to get the final Reflection type you need from the cache.
There are two methods for most operations like this:
Type typeofString = cache.GetType("System.String"); // <-- caches, stops the cache chain
CachedType type = cache.GetCachedType("System.String"); // <-- caches, continues the cache chain
Scenario: Retrieving parameters from a method
✅ Good:
CachedType cachedType = cache.GetCachedType("System.String");
CachedMethod cachedMethodInfo = cachedType.GetCachedMethod("Intern");
ParameterInfo?[] parameters = cachedMethodInfo.GetParameters(); // < -- parameters are now cached
❌ Bad:
CachedType cachedType = cache.GetCachedType("System.String");
MethodInfo methodInfo = cachedType.GetMethod("Intern"); // <-- uh oh, a non-cached Reflection type
ParameterInfo?[] parameters = methodInfo.GetParameters(); // <-- not cached, repeat calls are slow
Tips
- Almost all of the
Cached
methods (e.g.GetCachedParameters()
vsGetParameters()
are faster due to the final preparation needed to match the System.Reflection methods. - Work with the
Cached
objects instead of Reflection objects if possible. They're faster to retrieve and allow for more efficient downstream chaining. - Thread safety can be disabled for more speed. It's enabled by default.
- Consider if caching is even necessary for your use case. If you're only calling Reflection once, it may not be worth it.
- Caching isn't free. Be thoughtful of your memory footprint and where/when you dispose of the cache.
Notes
- A cache removal mechanism is needing to be built yet.
- Many Reflection functionalities are not yet implemented, and could benefit from caching.
- If you see something that could be improved (performance or allocation), please open an issue or PR.
Benchmarks (.NET 8.0)
GetType()
5,772% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetType_string_NoCache | 1,022.30 ns | 9.462 ns | 8.851 ns | baseline | |
GetType_string_Cache | 17.52 ns | 0.303 ns | 0.283 ns | 58.38x faster | 1.12x |
GetType_string_threadSafe_Cache | 24.73 ns | 0.139 ns | 0.116 ns | 41.29x faster | 0.33x |
GetCachedType_type_Cache | 12.21 ns | 0.234 ns | 0.218 ns | 83.76x faster | 1.74x |
GetCachedType_type_ThreadSafe_Cache | 19.01 ns | 0.067 ns | 0.052 ns | 53.73x faster | 0.47x |
GetMethods()
24,842% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetMethods_NoCache | 256.526 ns | 1.4587 ns | 1.2180 ns | baseline | |
GetMethods_Cache | 1.030 ns | 0.0412 ns | 0.0385 ns | 249.428x faster | 10.30x |
GetMethod()
37% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetMethod_NoCache | 23.06 ns | 0.234 ns | 0.208 ns | baseline | |
GetMethod_Cache | 16.77 ns | 0.079 ns | 0.070 ns | 1.37x faster | 0.01x |
GetMembers()
83,924% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetMembers_NoCache | 550.2334 ns | 4.1411 ns | 3.8736 ns | baseline | |
GetMembers_Cache | 0.6579 ns | 0.0515 ns | 0.0481 ns | 840.247x faster | 58.17x |
GetMembers_ThreadSafe_Cache | 0.7273 ns | 0.0307 ns | 0.0287 ns | 757.728x faster | 31.76x |
GetMember()
1,043% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetMember_NoCache | 136.57 ns | 1.353 ns | 1.266 ns | baseline | |
GetMember_Cache | 11.95 ns | 0.091 ns | 0.081 ns | 11.43x faster | 0.12x |
GetProperties()
8,960% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetProperties_NoCache | 58.5363 ns | 0.3463 ns | 0.3070 ns | baseline | |
GetProperties_Cache | 0.6502 ns | 0.0370 ns | 0.0328 ns | 90.25x faster | 4.59x |
GetProperties_ThreadSafe_Cache | 0.7169 ns | 0.0129 ns | 0.0108 ns | 81.72x faster | 1.36x |
GetProperty()
57% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetProperty_NoCache | 25.61 ns | 0.382 ns | 0.357 ns | baseline | |
GetProperty_Cache | 16.23 ns | 0.074 ns | 0.062 ns | 1.57x faster | 0.01x |
GetFields()
419% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetFields_NoCache | 48.941 ns | 0.9092 ns | 0.8505 ns | baseline | |
GetFields_Cache | 1.141 ns | 0.0512 ns | 0.0479 ns | 42.95x faster | 1.32x |
GetFields_ThreadSafe_Cache | 1.178 ns | 0.0144 ns | 0.0128 ns | 41.56x faster | 0.79x |
GetInterfaces()
1,439% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetInterfaces_NoCache | 13.1880 ns | 0.1197 ns | 0.0999 ns | baseline | |
GetInterfaces_Cache | 0.8649 ns | 0.0469 ns | 0.0439 ns | 15.39x faster | 0.58x |
GetInterface()
144% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetInterface_NoCache | 32.84 ns | 0.411 ns | 0.364 ns | baseline | |
GetInterface_Cache | 13.47 ns | 0.227 ns | 0.212 ns | 2.44x faster | 0.05x |
GetConstructors()
4,054% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetConstructors_NoCache | 38.4477 ns | 0.2020 ns | 0.1687 ns | baseline | |
GetConstructors_Cache | 0.9280 ns | 0.0109 ns | 0.0102 ns | 41.54x faster | 0.36x |
GetConstructors_ThreadSafe_Cache | 1.0120 ns | 0.0689 ns | 0.0645 ns | 38.39x faster | 2.42x |
GetConstructor()
601% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetConstructor_NoCache | 18.16 ns | 0.298 ns | 0.278 ns | baseline | |
GetConstructor_NoCache_Parameters | 127.18 ns | 1.592 ns | 1.489 ns | 7.01x slower | 0.16x |
GetConstructor_Cache | 10.36 ns | 0.057 ns | 0.048 ns | 1.76x faster | 0.03x |
GetConstructor_Cache_Parameters | 21.12 ns | 0.366 ns | 0.342 ns | 1.16x slower | 0.02x |
Activator.CreateInstance(params)
vs cachedConstructor.CreateInstance(params)
242% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
Activator_Create_with_parameters | 325.58 ns | 1.713 ns | 1.431 ns | baseline | |
Cache_CreateInstance_with_parameters | 95.61 ns | 1.943 ns | 1.908 ns | 3.42x faster | 0.07x |
GetCustomAttributes()
1,658% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetAttributes_NoCache | 2,560.76 ns | 6.740 ns | 6.305 ns | baseline | |
GetAttributes_Cache | 15.35 ns | 0.287 ns | 0.268 ns | 166.858x faster | 2.97x |
GetGenericTypeDefinition()
499% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetGenericTypeDefinition_NoCache | 1.8759 ns | 0.0481 ns | 0.0450 ns | baseline | |
GetGenericTypeDefinition_Cache | 0.3159 ns | 0.0313 ns | 0.0293 ns | 5.99x faster | 0.58x |
IsAssignableFrom()
51% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
IsAssignableFrom_NoCache | 9.355 ns | 0.1357 ns | 0.1270 ns | baseline | |
IsAssignableFrom_Cache | 6.198 ns | 0.0794 ns | 0.0742 ns | 1.51x faster | 0.04x |
MakeGenericType()
1,485% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
MakeGenericType_NoCache | 158.56 ns | 0.900 ns | 0.842 ns | baseline | |
MakeGenericType_Cache | 10.01 ns | 0.216 ns | 0.202 ns | 15.85x faster | 0.31x |
GetElementType()
1,847% faster
Method | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|
GetElementType_NoCache | 4.9175 ns | 0.0442 ns | 0.0369 ns | baseline | |
GetElementType_Cache | 0.2585 ns | 0.0204 ns | 0.0191 ns | 19.47x faster | 1.06x |
Properties on Type
(e.g. typeof(string).IsNullable
)
Method | Mean | Error | StdDev | Median |
---|---|---|---|---|
IsAbstract_NoCache | 2.4277 ns | 0.0319 ns | 0.0299 ns | 2.4152 ns |
IsAbstract_Cache | 0.0000 ns | 0.0000 ns | 0.0000 ns | 0.0000 ns |
IsInterface_NoCache | 0.7720 ns | 0.0219 ns | 0.0194 ns | 0.7662 ns |
IsInterface_Cache | 0.0045 ns | 0.0076 ns | 0.0071 ns | 0.0000 ns |
IsGenericType_NoCache | 0.8707 ns | 0.0281 ns | 0.0262 ns | 0.8732 ns |
IsGenericType_Cache | 0.2667 ns | 0.0195 ns | 0.0182 ns | 0.2651 ns |
IsEnum_NoCache | 0.5322 ns | 0.0242 ns | 0.0227 ns | 0.5291 ns |
IsEnum_Cache | 0.2612 ns | 0.0251 ns | 0.0235 ns | 0.2526 ns |
IsNullable_NoCache | 1.4296 ns | 0.0297 ns | 0.0278 ns | 1.4305 ns |
IsNullable_Cache | 0.2312 ns | 0.0077 ns | 0.0065 ns | 0.2278 ns |
IsByRef_NoCache | 1.8439 ns | 0.0332 ns | 0.0310 ns | 1.8410 ns |
IsByRef_Cache | 0.0012 ns | 0.0025 ns | 0.0022 ns | 0.0000 ns |
IsArray_NoCache | 2.2914 ns | 0.0484 ns | 0.0452 ns | 2.2652 ns |
IsArray_Cache | 0.0060 ns | 0.0102 ns | 0.0096 ns | 0.0000 ns |
Notes:
- These benchmarks are built over iterations. The first operation is going to be as slow as the Reflection it sits in front of.
- Many of these are based off of a test class
TestType
which is located in the test library.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.1)
- Soenneker.Extensions.Array.Object (>= 2.1.12)
- Soenneker.Extensions.ParameterInfo (>= 2.1.11)
-
net7.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.1)
- Soenneker.Extensions.Array.Object (>= 2.1.12)
- Soenneker.Extensions.ParameterInfo (>= 2.1.11)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.1)
- Soenneker.Extensions.Array.Object (>= 2.1.12)
- Soenneker.Extensions.ParameterInfo (>= 2.1.11)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Soenneker.Reflection.Cache:
Package | Downloads |
---|---|
Soenneker.Cosmos.Serializer
A fast, lightweight JSON (de)serializer for Azure Cosmos DB |
|
Soenneker.Utils.AutoBogus
The .NET Bogus autogenerator |
|
Soenneker.Utils.String
A utility library for useful String operations |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.1.162 | 4,932 | 8/13/2024 |
2.1.161 | 7,171 | 8/6/2024 |
2.1.160 | 4,312 | 8/1/2024 |
2.1.159 | 3,258 | 7/31/2024 |
2.1.158 | 4,527 | 7/25/2024 |
2.1.157 | 34 | 7/25/2024 |
2.1.156 | 1,992 | 7/24/2024 |
2.1.155 | 12,767 | 7/14/2024 |
2.1.154 | 6,994 | 7/10/2024 |
2.1.153 | 3,504 | 7/10/2024 |
2.1.151 | 1,346 | 7/9/2024 |
2.1.149 | 100 | 7/9/2024 |
2.1.148 | 5,893 | 7/9/2024 |
2.1.147 | 3,472 | 7/9/2024 |
2.1.146 | 71 | 7/9/2024 |
2.1.145 | 1,234 | 7/9/2024 |
2.1.144 | 71 | 7/9/2024 |
2.1.143 | 3,319 | 7/9/2024 |
2.1.141 | 552 | 7/8/2024 |
2.1.140 | 65 | 7/8/2024 |
2.1.139 | 64 | 7/8/2024 |
2.1.138 | 1,341 | 7/8/2024 |
2.1.137 | 7,744 | 7/7/2024 |
2.1.136 | 1,001 | 7/7/2024 |
2.1.135 | 10,152 | 7/3/2024 |
2.1.134 | 12,148 | 6/15/2024 |
2.1.133 | 8,832 | 6/1/2024 |
2.1.132 | 59 | 6/1/2024 |
2.1.131 | 456 | 6/1/2024 |
2.1.130 | 5,272 | 5/31/2024 |
2.1.129 | 3,035 | 5/29/2024 |
2.1.128 | 3,405 | 5/28/2024 |
2.1.127 | 2,205 | 5/27/2024 |
2.1.126 | 6,444 | 5/25/2024 |
2.1.125 | 1,772 | 5/25/2024 |
2.1.124 | 117 | 5/25/2024 |
2.1.123 | 85 | 5/25/2024 |
2.1.122 | 1,177 | 5/25/2024 |
2.1.121 | 91 | 5/25/2024 |
2.1.120 | 85 | 5/25/2024 |
2.1.119 | 89 | 5/25/2024 |
2.1.118 | 84 | 5/25/2024 |
2.1.117 | 12,432 | 5/23/2024 |
2.1.116 | 1,677 | 5/22/2024 |
2.1.115 | 1,411 | 5/22/2024 |
2.1.114 | 85 | 5/22/2024 |
2.1.113 | 87 | 5/22/2024 |
2.1.112 | 170 | 5/22/2024 |
2.1.111 | 3,400 | 5/22/2024 |
2.1.110 | 6,200 | 5/17/2024 |
2.1.109 | 6,353 | 5/14/2024 |
2.1.108 | 60 | 5/14/2024 |
2.1.107 | 10,680 | 4/29/2024 |
2.1.106 | 112 | 4/29/2024 |
2.1.105 | 3,497 | 4/28/2024 |
2.1.104 | 2,242 | 4/28/2024 |
2.1.103 | 85 | 4/28/2024 |
2.1.102 | 2,815 | 4/28/2024 |
2.1.101 | 88 | 4/28/2024 |
2.1.100 | 1,588 | 4/28/2024 |
2.1.99 | 84 | 4/28/2024 |
2.1.98 | 83 | 4/28/2024 |
2.1.97 | 84 | 4/28/2024 |
2.1.96 | 463 | 4/27/2024 |
2.1.95 | 86 | 4/27/2024 |
2.1.94 | 999 | 4/27/2024 |
2.1.93 | 11,942 | 4/12/2024 |
2.1.92 | 2,914 | 4/12/2024 |
2.1.91 | 92 | 4/12/2024 |
2.1.90 | 105 | 4/12/2024 |
2.1.89 | 104 | 4/12/2024 |
2.1.88 | 109 | 4/12/2024 |
2.1.87 | 97 | 4/12/2024 |
2.1.86 | 2,223 | 4/12/2024 |
2.1.85 | 101 | 4/12/2024 |
2.1.84 | 7,041 | 4/9/2024 |
2.1.83 | 3,536 | 4/1/2024 |
2.1.82 | 6,120 | 3/25/2024 |
2.1.81 | 4,049 | 3/19/2024 |
2.1.80 | 6,058 | 3/13/2024 |
2.1.79 | 91 | 3/13/2024 |
2.1.78 | 921 | 3/13/2024 |
2.1.77 | 90 | 3/13/2024 |
2.1.76 | 92 | 3/13/2024 |
2.1.75 | 2,730 | 3/12/2024 |
2.1.74 | 94 | 3/12/2024 |
2.1.73 | 7,689 | 3/8/2024 |
2.1.72 | 3,676 | 3/6/2024 |
2.1.71 | 1,971 | 3/4/2024 |
2.1.70 | 3,710 | 3/2/2024 |
2.1.69 | 1,524 | 3/2/2024 |
2.1.68 | 2,434 | 2/29/2024 |
2.1.67 | 4,600 | 2/25/2024 |
2.1.66 | 3,716 | 2/22/2024 |
2.1.65 | 2,064 | 2/21/2024 |
2.1.64 | 586 | 2/21/2024 |
2.1.63 | 1,301 | 2/21/2024 |
2.1.62 | 92 | 2/21/2024 |
2.1.61 | 105 | 2/21/2024 |
2.1.60 | 95 | 2/21/2024 |
2.1.59 | 98 | 2/21/2024 |
2.1.58 | 1,101 | 2/20/2024 |
2.1.57 | 3,084 | 2/20/2024 |
2.1.56 | 2,666 | 2/19/2024 |
2.1.55 | 102 | 2/19/2024 |
2.1.54 | 102 | 2/19/2024 |
2.1.53 | 106 | 2/18/2024 |
2.1.52 | 3,982 | 2/16/2024 |
2.1.51 | 97 | 2/16/2024 |
2.1.50 | 741 | 2/16/2024 |
2.1.49 | 1,206 | 2/16/2024 |
2.1.48 | 753 | 2/16/2024 |
2.1.47 | 1,451 | 2/16/2024 |
2.1.46 | 2,104 | 2/13/2024 |
2.1.45 | 2,088 | 2/13/2024 |
2.1.44 | 95 | 2/13/2024 |
2.1.43 | 98 | 2/13/2024 |
2.1.42 | 3,114 | 2/11/2024 |
2.1.41 | 2,217 | 2/11/2024 |
2.1.40 | 1,158 | 2/10/2024 |
2.1.39 | 96 | 2/10/2024 |
2.1.38 | 93 | 2/10/2024 |
2.1.37 | 120 | 2/9/2024 |
2.1.36 | 2,401 | 2/9/2024 |
2.1.35 | 1,500 | 2/9/2024 |
2.1.34 | 96 | 2/9/2024 |
2.1.33 | 1,380 | 2/8/2024 |
2.1.32 | 1,163 | 2/8/2024 |
2.1.31 | 1,122 | 2/8/2024 |
2.1.30 | 2,811 | 2/6/2024 |
2.1.29 | 1,070 | 2/6/2024 |
2.1.28 | 86 | 2/6/2024 |
2.1.27 | 2,170 | 2/6/2024 |
2.1.26 | 94 | 2/6/2024 |
2.1.25 | 126 | 2/5/2024 |
2.1.24 | 2,855 | 2/4/2024 |
2.1.23 | 88 | 2/4/2024 |
2.1.22 | 1,280 | 2/2/2024 |
2.1.21 | 85 | 2/1/2024 |
2.1.20 | 86 | 2/1/2024 |
2.1.19 | 102 | 2/1/2024 |
2.1.18 | 92 | 1/31/2024 |
2.1.17 | 83 | 1/31/2024 |
2.1.16 | 1,690 | 1/30/2024 |
2.1.15 | 3,950 | 1/28/2024 |
2.1.14 | 7,417 | 1/27/2024 |
2.1.13 | 776 | 1/26/2024 |
2.1.12 | 5,805 | 1/25/2024 |
2.1.11 | 91 | 1/25/2024 |
2.1.10 | 85 | 1/25/2024 |
2.1.9 | 88 | 1/25/2024 |
2.1.8 | 84 | 1/25/2024 |
2.1.7 | 2,180 | 1/23/2024 |
2.1.6 | 95 | 1/21/2024 |