Last active
February 10, 2018 08:56
-
-
Save iwillspeak/2f97766aef7a1f44f5c4feb89f65ffd8 to your computer and use it in GitHub Desktop.
Demonstration of caching of derived type information using the curiously recurring template pattern
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
root = true | |
[*.cs] | |
indent_style = space | |
indent_size = 4 |
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
bin/ | |
obj/ | |
BenchmarkDotNet.Artifacts/ |
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
using System; | |
using System.Reflection; | |
using System.Linq; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
namespace crtp | |
{ | |
using foo; | |
using bar; | |
using baz; | |
namespace foo | |
{ | |
public class FooBase | |
{ | |
public FooBase() | |
{ | |
_props = CrtpBench.GetProperties(GetType()); | |
} | |
private IDictionary<string, PropertyInfo> _props; | |
} | |
public class Foo : FooBase | |
{ | |
public string F { get; } | |
public int B { get; } | |
} | |
} | |
namespace bar | |
{ | |
public class BarBase<T> | |
{ | |
private static IDictionary<string, PropertyInfo> Props = CrtpBench.GetProperties(typeof(T)); | |
} | |
public class Bar : BarBase<Bar> | |
{ | |
public string F { get; } | |
public int B { get; } | |
} | |
} | |
namespace baz | |
{ | |
public class BazBase | |
{ | |
public BazBase() | |
{ | |
_props = TypeProps.GetOrAdd(GetType(), CrtpBench.GetProperties); | |
} | |
private IDictionary<string, PropertyInfo> _props; | |
private static ConcurrentDictionary<Type, IDictionary<string, PropertyInfo>> TypeProps = | |
new ConcurrentDictionary<Type, IDictionary<string, PropertyInfo>>(); | |
} | |
public class Baz : BazBase | |
{ | |
public string F { get; } | |
public int B { get; } | |
} | |
} | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var summary = BenchmarkRunner.Run<CrtpBench>(); | |
} | |
} | |
[MemoryDiagnoser] | |
public class CrtpBench | |
{ | |
public static IDictionary<string, PropertyInfo> GetProperties(Type t) => | |
t.GetMembers() | |
.Where(mi => mi.MemberType==MemberTypes.Property) | |
.Cast<PropertyInfo>() | |
.ToDictionary(prop => prop.Name); | |
[Benchmark] | |
public Foo Standard() => new Foo(); | |
[Benchmark] | |
public Baz StaticCache() => new Baz(); | |
[Benchmark] | |
public Bar Crtp() => new Bar(); | |
} | |
} |
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
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>netcoreapp2.0</TargetFramework> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="BenchmarkDotNet" Version="0.10.12" /> | |
</ItemGroup> | |
</Project> |
// * Summary *
BenchmarkDotNet=v0.10.12, OS=macOS 10.13.2 (17C88) [Darwin 17.3.0]
Intel Core i7-4980HQ CPU 2.80GHz (Haswell), 1 CPU, 8 logical cores and 4 physical cores
.NET Core SDK=2.0.0
[Host] : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT
DefaultJob : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT
Method | Mean | Error | StdDev | Gen 0 | Allocated |
------------ |-------------:|----------:|----------:|-------:|----------:|
Standard | 1,153.020 ns | 9.1427 ns | 7.1380 ns | 0.0954 | 600 B |
StaticCache | 40.069 ns | 0.5370 ns | 0.5023 ns | 0.0165 | 104 B |
Crtp | 4.095 ns | 0.1147 ns | 0.1072 ns | 0.0051 | 32 B |
// * Hints *
Outliers
CrtpBench.Standard: Default -> 3 outliers were removed
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Gen 0 : GC Generation 0 collects per 1k Operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 ns : 1 Nanosecond (0.000000001 sec)
// * Diagnostic Output - MemoryDiagnoser *
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Execute with