现在的位置: 首页 > 综合 > 正文

利用CodeDom来解决反射性能问题

2013年04月07日 ⁄ 综合 ⁄ 共 1386字 ⁄ 字号 评论关闭

前段时间在cnblogs看到了一编文章《利用Emit减少反射的性能损失》原文(http://yok.cnblogs.com/archive/2005/11/03/267952.html);
在编写一个数据处理组件时面对着这样的问题,一个反射操作所消耗的时间虽然很短;但在对象和数据换转之间存在着大量的反射操作,大量反射操下效率就有点令人担心.为了验证这一点于是采用动态编译操作对象来避开反射操作.基于方便容易用我没有选择Emit,而采用CodeDom.两者性能在整休上应该差别不大,因为通过CodeDom生成操作对象后缓存起来,在后期调时直接从缓存中获取不需要重新编译.
    通过CodeDom生成获取数据到实体对象的代码:
 public object CreateInstance()
 {
  return new Order();
 }
 public  void LoadInfo(object entity,System.Data.IDataReader pDataReader)
  {
    Order Item = (Order)entity;
    if(pDataReader["OrderID"] != DBNull.Value)
    {
     Item .OrderID= (Int32)pDataReader["OrderID"];
    }
    if(pDataReader["CustomerID"] != DBNull.Value)
    {
     Item .CustomerID= (String)pDataReader["CustomerID"];
    }
   ..............
  }
以上代码在内存编译后,其操作的效率和正常编写代码的效率差不多并不会有太大的差异.为了方便调用可以制定接口规范.
进行测试情况如下:
测试电脑配置
P41.7,512内存
测试表结构.
2 OrderID int 4 
0 CustomerID nchar 
0 EmployeeID int 
0 OrderDate datetime 
0 RequiredDate datetime 
0 ShippedDate datetime 
0 ShipVia int 4 
0 Freight money 8 
0 ShipName nvarchar 
0 ShipAddress nvarchar 
0 ShipCity nvarchar 
0 ShipRegion nvarchar 
0 ShipPostalCode nvarchar 
1 ShipCountry nvarchar 
830条记录获取测试情况,运行10次第一次和最后一次不要取其中8次的平均时间(查看方便只保留3位小数).
0.040(秒) CodeDom映射到实体集合
0.123(秒) .NET的反射功能的映射到实体集合(反射信息已缓存)
0.024(秒) 直接填充到DataSet

从测试结果来看,运用CodeDom编译操作对象代替反射操作的效率有明显提高.前面的操作代码也可以作改进,把键值用索引来代替效率和直接填充DataSet会更接近(测试过用索引取值比用键值取值大概快2-3微秒)。
    常用的工厂类经常通过反射来实现对象创建,可以利用这技术解决效率问题;这种技术虽然有它的好处,但实现起来有点麻烦,也消耗内存;所以可以根据实际情况来利用。

抱歉!评论已关闭.