简单的 emit expression and reflected 性能比较

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();
}



posted on 2011-12-26 18:12  Terry@  阅读(546)  评论(1编辑  收藏  举报

导航