优化反射性能的总结反射是一种很重要的技术,然而它与直接调用相比性能要慢很多,因此如何优化反射性能也就成为一个不得不面对的问题。目前最常见的优 化反射性能的方法就是采用委托:用委托的方式调用需要反射调用的方法(或者属性、字段)。那么如何得到委托呢?目前最常见也就是二种方 法:Emit,ExpressionTree。其中ExpressionTree可认为是Emit方法的简化版本,所以Emit是最根 本的方法,它采用在运行时动态构造一段IL代码来包装需要反射调用的代码,这段动态生成的代码满足某个委托的签名,因此最后可以采用委托的 方式代替反射调用。http://www.cnblogs.com/fish-li/archive/2013/02/18/29162 53.html回到顶部用Emit方法优化反射如果我们需要设计自己的数据访问层,那么就需要动态创建所有的数据实体对象,尤其是还要为每 个数据实体对象的属性赋值,这里就要涉及用反射的方法对属性执行写操作,为了优化这种反射场景的性能,我们可以用下面的方法来实现:现在 可以用下面的测试代码检验委托调用带来的性能改进:我用VS2008(.net3.5,CLR2.0)测试可以得到以下结果 :从结果可以看出:1.反射调用所花时间是直接调用的2629倍,2.反射调用所花时间是Emit生成的Set委托代码的82倍,3 .运行Emit生成的Set委托代码所花时间是直接调用的31倍。虽然Emit比直接调用还有30倍的差距,但还是比反射调用快80倍 左右。有意思的是,同样的代码,如果用VS2012(.net4.5,CLR4.0)测试可以得到以下结果:感谢htt p://www.cnblogs.com/lemontea/archive/2013/02/04/2891281.htmlzhang weiwen在博客中展示了CRL4.0对反射的性能改进,在他的博客中还提供了一种采用表达式树的优化版本,以及包含一个泛型的强类 型的版本。http://www.cnblogs.com/fish-li/archive/2013/02/18/2916253.h tml回到顶部Delegate.CreateDelegate也能创建委托如果我们观察CreatePropertySetter的实现 代码,发现这个方法的本质就是创建一个委托:publicstaticSetValueDelegateCreateProper tySetter(PropertyInfoproperty){//.....省略前面已贴过的代码return(SetV alueDelegate)dm.CreateDelegate(typeof(SetValueDelegate));}看到这里,让我 想起Delegate.CreateDelegate方法也能创建一个委托,例如:OrderInfotestObj=newO rderInfo();PropertyInfopropInfo=typeof(OrderInfo).GetProperty( "OrderID");Actionsetter=(Action>)Delegate.CreateDelegate(typeof(Action),null, propInfo.GetSetMethod());setter(testObj,123);显然,这是一种很直观的方法,可以得到一 个强类型的委托。然而,这种方法仅限有一种适用场景:明确知道要访问某个类型的某个属性或者方法,因为我们要提供类型参数。例如:我要 写个关键字过滤的HttpMoudle,它需要修改HttpRequest.Form对象的IsReadOnly属性,由于IsReadO nly在NameObjectCollectionBase类型中已申明为protected访问级别,所以我只能反射操作它了,而且还需 要很频繁的设置它。在绝大部分反射场景中,例如数据访问层中从DataReader或者DataRow加载数据实体,我们不可能事先知道 要加载哪些类型,更不可能知道要加载哪些数据成员,因此就不可能给泛型委托的类型参数赋值,这个方法看起来也就行不通了。如果您不信的话, 可以看下面修改后的代码:OrderInfotestObj=newOrderInfo();PropertyInfopro pInfo=typeof(OrderInfo).GetProperty("OrderID");//Actionfo,int>setter=(Action)Delegate.CreateDelegate (//typeof(Action),null,propInfo.GetSetMethod()) ;Action |
|