本文主要转自
再谈Activator.CreateInstance(Type type)方法创建对象和Expression Tree创建对象性能的比较(更新版)
探究.net对象的创建,质疑《再谈Activator.CreateInstance(Type type)方法创建对象和Expression Tree创建对象性能的比较》
Activator.CreateInstance 方法创建对象和Expression Tree创建对象性能的比较(构造函数含多参数的情况)
表达式树对性能的影响
以下是对动态属性传值等操作的收集
晚绑定场景下对象属性赋值和取值可以不需要PropertyInfo
三种属性操作性能比较:PropertyInfo + Expression Tree + Delegate.CreateDelegate
关于Expression Tree和IL Emit的所谓的"性能差别"
-------------------------------------------------------------------------------------------------
表达式树解析"框架"(1)
.net中反射、emit、expression和dynamic的性能比较
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();
}
测试结果
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