Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
public class Dummy
{
public bool BoolField;
public void SetBool(bool value)
{
BoolField = value;
}
public bool GetBool()
{
return BoolField;
}
}
[Config(typeof(Config))]
public class DynamicCodeGeneration
{
private static readonly MethodInfo SetBool = typeof(Dummy).GetMethod(nameof(Dummy.SetBool));
private static readonly MethodInfo GetBool = typeof(Dummy).GetMethod(nameof(Dummy.GetBool));
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<DynamicCodeGeneration>();
}
private class Config : ManualConfig
{
public Config()
{
Add(Job.Clr.WithLaunchCount(1).WithWarmupCount(5).WithTargetCount(5));
Add(new MemoryDiagnoser());
Add(new InliningDiagnoser());
Add(JitOptimizationsValidator.FailOnError);
Add(RPlotExporter.Default);
}
}
private static Dummy dummy = new Dummy();
private static Action<Dummy, bool> dynamicWrite;
private static Func<Dummy, bool> dynamicRead;
static DynamicCodeGeneration()
{
{
var compileWrite = new IlCompiler<Action<Dummy, bool>>();
var param = compileWrite.Parameter<Dummy>("dummy");
var arg = compileWrite.Parameter<bool>("value");
compileWrite.EmitCall(SetBool, param, arg);
dynamicWrite = compileWrite.Compile();
}
{
var compileRead = new IlCompiler<Func<Dummy, bool>>();
var paramRead = compileRead.Parameter<Dummy>("dummy");
compileRead.EmitCall(GetBool, paramRead);
dynamicRead = compileRead.Compile();
}
}
[Benchmark]
public void PropertyWrite()
{
dummy.BoolField = false;
}
[Benchmark]
public void PropertyWriteReflection()
{
SetBool.Invoke(dummy, new object[] { false });
}
[Benchmark]
public void PropertyWriteDynamicCode()
{
dynamicWrite(dummy, false);
}
[Benchmark]
public bool PropertyRead()
{
//return dummy.BoolField;
return dummy.GetBool();
}
[Benchmark]
public bool PropertyReadReflection()
{
return (bool)GetBool.Invoke(dummy, new object[] { });
}
[Benchmark]
public bool PropertyReadDynamicCode()
{
return dynamicRead(dummy);
}
}
@mattwarren
Owner

Results:

image

@mattwarren
Owner
Host Process Environment Information:
BenchmarkDotNet.Core=v0.9.9.0
OS=Microsoft Windows NT 6.1.7601 Service Pack 1
Processor=Intel(R) Core(TM) i7-4800MQ CPU 2.70GHz, ProcessorCount=8
Frequency=2630761 ticks, Resolution=380.1181 ns, Timer=TSC
CLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
GC=Concurrent Workstation
JitModules=clrjit-v4.6.1076.0

Type=DynamicCodeGeneration  Mode=Throughput  Toolchain=Clr  
Runtime=Clr  LaunchCount=1  WarmupCount=5  
TargetCount=5  
Method Median StdDev Gen 0 Gen 1 Gen 2 Bytes Allocated/Op
PropertyWrite 0.0667 ns 0.0452 ns - - - 0.00
PropertyWriteReflection 269.5551 ns 11.8874 ns 165.00 - - 16.06
PropertyWriteDynamicCode 1.5064 ns 0.1918 ns - - - 0.00
PropertyRead 0.0000 ns 0.0000 ns - - - 0.00
PropertyReadReflection 193.3971 ns 12.0583 ns 92.69 - - 8.50
PropertyReadDynamicCode 1.4945 ns 0.0583 ns - - - 0.00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment