利用CodeDom来解决反射性能问题
前段时间在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微秒)。
常用的工厂类经常通过反射来实现对象创建,可以利用这技术解决效率问题;这种技术虽然有它的好处,但实现起来有点麻烦,也消耗内存;所以可以根据实际情况来利用。