I've been benchmarking some code that creates an instance of a type and this result seemed weird to me:
Delegate deleg = Expression.Lambda(Expression.New(_type)).Compile();
// deleg.DynamicInvoke();
vs
Func<object> func = Expression.Lambda<Func<object>>(Expression.New(_type)).Compile();
// func();
Using BenchmarDotNet gives (Mean, Core):
- Delegate: 501.790 ns
- Func: 4.710 ns
Anyone knows why the difference is so huge?
Complete benchmarks:
[ClrJob(baseline: true), CoreJob, CoreRtJob]
[RPlotExporter, RankColumn]
public class Benchmarks
{
private Type _type;
private ConstructorInfo _constructor;
private Delegate _delegate;
private Func<object> _func;
[GlobalSetup]
public void GlobalSetup()
{
_type = typeof(TestClass);
_constructor = _type.GetConstructor(Type.EmptyTypes);
_delegate = Expression.Lambda(Expression.New(_type)).Compile();
_func = Expression.Lambda<Func<object>>(Expression.New(_type)).Compile();
}
[Benchmark(Baseline = true)]
public object Instanciate_Using_New()
{
return new TestClass();
}
[Benchmark]
public object Instanciate_Using_Activator()
{
return Activator.CreateInstance(_type);
}
[Benchmark]
public object Instanciate_Using_Constructor()
{
return _constructor.Invoke(null);
}
[Benchmark]
public object Instanciate_Using_Expression_Delegate()
{
return _delegate.DynamicInvoke();
}
[Benchmark]
public object Instanciate_Using_Expression_Func()
{
return _func();
}
}