I modified your code slightly so that it could be compiled using all .NET versions.
With .NET2 and 3.5 there was no difference in execution time between the standard and dynamic methods, both taking about 1400 - 1500ms in release mode.
However .NET 4 (v4.0.30319) was a different story altogether. The results were similar to yours with 1400 for the standard and 19700ms for the dynamic method.
My modified method, with the speedup fix commented out, is:
public static Action<T1, T2> CreateCopier<T1, T2>() {
DynamicMethod meth = new DynamicMethod(
"copy",
null,
new Type[] { typeof(T1), typeof(T2) },
true);
ILGenerator il = meth.GetILGenerator();
int cpt = 0;
foreach (PropertyInfo mi1 in typeof(T1).GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
PropertyInfo mi2 = typeof(T2).GetProperty(mi1.Name, BindingFlags.Public | BindingFlags.Instance);
if (mi1 != null && mi2 != null) {
cpt++;
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, mi1.GetGetMethod());
il.Emit(OpCodes.Callvirt, mi2.GetSetMethod());
}
}
il.Emit(OpCodes.Ret);
Delegate dlg = meth.CreateDelegate(typeof(Action<T1, T2>));
return (Action<T1, T2>)dlg;
}
The big slow down in execution time is caused when the dynamic method is associated with an anonymous assembly by using the
DynamicMethod(string, Type, Type[], bool)
constructor. I would guess that .NET 4 is doing more security checks than the previous versions, although I have no insight into, or explanation for, what is actually going on.
Associating the method with a Type by using the
DynamicMethod(string, Type, Type[], Type, bool)
constructor completely removes the speed penalty.
There are some notes on MSDN which may be relevant (if only I could understand them!)
http://msdn.microsoft.com/en-us/library/bb348332(v=vs.100).aspx[
^]
http://msdn.microsoft.com/en-us/library/9syytdak.aspx[
^]
Alan.