class
Student
{
public string Name { get ; set ; }
}
static double Test( int loop, Student stu, Func < Student, string > action)
{
var watch = Stopwatch.StartNew();
string s = null ;
for (var i = 0 ; i < loop; i ++ )
s = action(stu);
return watch.ElapsedTicks;
}
static Func < Student, string > NativeGetter()
{
return s => s.Name;
}
static Func < Student, string > ReflectedGetter()
{
var type = typeof (Student);
var prop = type.GetProperty( " Name " );
return s => ( string )prop.GetValue(s, null );
}
static Func < Student, string > EmittedGetter()
{
var dm = new DynamicMethod(name: " EmittedGetter " , returnType: typeof ( string ), parameterTypes: new [] { typeof (Student) }, owner: typeof (Student));
var type = typeof (Student);
var prop = type.GetMethod( " get_Name " );
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, prop);
il.Emit(OpCodes.Ret);
return (Func < Student, string > )dm.CreateDelegate( typeof (Func < Student, string > ));
}
static Func < Student, string > ExpressionGetter()
{
var type = typeof (Student);
var prop = type.GetMethod( " get_Name " );
ParameterExpression pa = Expression.Parameter( typeof (Student));
Expression body = Expression.Call(pa, prop);
return Expression.Lambda < Func < Student, string >> (body, pa).Compile();
}
static Func < Student, string > DynamicGetter()
{
return s => { dynamic d = s; return d.Name; };
}
[MethodImpl(MethodImplOptions.NoOptimization)]
public static void Run()
{
const int loop = 5000000 ;
var stu = new Student {Name = " Mike " };
var dynamic =
Test(loop, stu, DynamicGetter());
var expression =
Test(loop, stu, ExpressionGetter());
var native =
Test(loop, stu, NativeGetter());
var emitted =
Test(loop, stu, EmittedGetter());
var reflected =
Test(loop, stu, ReflectedGetter());
Console.WriteLine( " native:{0}\ndynamic:{1}\nemit:{2}\nexpression:{3}\nreflection:{4} " , 1 , dynamic / native, emitted / native, expression / native, reflected / native);
Console.ReadKey();
}
{
public string Name { get ; set ; }
}
static double Test( int loop, Student stu, Func < Student, string > action)
{
var watch = Stopwatch.StartNew();
string s = null ;
for (var i = 0 ; i < loop; i ++ )
s = action(stu);
return watch.ElapsedTicks;
}
static Func < Student, string > NativeGetter()
{
return s => s.Name;
}
static Func < Student, string > ReflectedGetter()
{
var type = typeof (Student);
var prop = type.GetProperty( " Name " );
return s => ( string )prop.GetValue(s, null );
}
static Func < Student, string > EmittedGetter()
{
var dm = new DynamicMethod(name: " EmittedGetter " , returnType: typeof ( string ), parameterTypes: new [] { typeof (Student) }, owner: typeof (Student));
var type = typeof (Student);
var prop = type.GetMethod( " get_Name " );
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, prop);
il.Emit(OpCodes.Ret);
return (Func < Student, string > )dm.CreateDelegate( typeof (Func < Student, string > ));
}
static Func < Student, string > ExpressionGetter()
{
var type = typeof (Student);
var prop = type.GetMethod( " get_Name " );
ParameterExpression pa = Expression.Parameter( typeof (Student));
Expression body = Expression.Call(pa, prop);
return Expression.Lambda < Func < Student, string >> (body, pa).Compile();
}
static Func < Student, string > DynamicGetter()
{
return s => { dynamic d = s; return d.Name; };
}
[MethodImpl(MethodImplOptions.NoOptimization)]
public static void Run()
{
const int loop = 5000000 ;
var stu = new Student {Name = " Mike " };
var dynamic =
Test(loop, stu, DynamicGetter());
var expression =
Test(loop, stu, ExpressionGetter());
var native =
Test(loop, stu, NativeGetter());
var emitted =
Test(loop, stu, EmittedGetter());
var reflected =
Test(loop, stu, ReflectedGetter());
Console.WriteLine( " native:{0}\ndynamic:{1}\nemit:{2}\nexpression:{3}\nreflection:{4} " , 1 , dynamic / native, emitted / native, expression / native, reflected / native);
Console.ReadKey();
}
测试结果
1. 当循环次数比较小的时候, loop=1000
native:1
dynamic:540.444964871194
emit:0.704918032786885
expression:0.224824355971897
reflection:8.37002341920375
2. loop=5000000
native:1
dynamic:4.37328053807767
emit:0.96159470600998
expression:1.00412887828162
reflection:35.909097418095