Faster, less leakier thread-safe Lazy<T> implementation in C#.
Lazy<T>
is an excellent general purpose implementation for lazily instantiated types. However, it is inappropriate for the scenarios where both of the following are true:
- You are using
Lazy<T>
in a concurrent context where multiple publish events may occur simultaneously and typeT
is anIDisposable
resource. Using eitherLazyThreadSafetyMode.None
orLazyThreadSafetyMode.PublicationOnly
will result in a resource leak during this scenario. - You are using
Lazy<T>
in a performance-sensitive context where the cost of using alock
operation isn't acceptable, hence you cannot useLazy<T>
withLazyThreadSafetyMode.ExecutionAndPublication
.
If both of the above are true, then you should use FastLazy<T>
in this library.
FastLazy<T>
guarantees the following:
- The lazy value of type
T
will be instantiated exactly once, even if many concurrent instantiation calls are happening simultaneously (threadsafe, singleton instantiation.) Spec to verify. - The same instance of
T
will be served on everyFastLazy<T>.Value
call (threadsafe reads.) Spec to verify. FastLazy<T>.Value
calls will significantly outperform the equivalentLazy<T>.Value
call (lock-free, threadsafe reads.) Benchmark to verify.
FastLazy<T>
will not cache exceptions thrown by the factory method, nor will it perform any of the other niceties included inside System.Lazy<T>
. It relies on the user to do the right thing.
FastLazy<T>
is up to twice as fast as the non-threadsafe verison of Lazy<T>
.
BenchmarkDotNet=v0.9.7.0
OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-3630QM CPU 2.40GHz, ProcessorCount=8
Frequency=2338442 ticks, Resolution=427.6352 ns, Timer=TSC
HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE [AttachedDebugger]
JitModules=clrjit-v4.6.1080.0
Type=FastLazyBenchmarks Mode=Throughput
Method | Median | StdDev |
---|---|---|
ReadFastLazy | 1.2866 ns | 0.1015 ns |
ReadLazyNotThreadSafe | 2.8733 ns | 0.0448 ns |
ReadLazyPublishOnlyThreadSafe | 2.8824 ns | 0.0993 ns |
ReadLazyReadAndExecuteThreadSafe | 2.8793 ns | 0.0524 ns |