DataReder填充对象集比DataAdapter.Fill效率要高?

    在做一个数据组件时查询时要把数据集转成对象集;在测试过程中看到的结果自己的感觉有点意外.DataReder填充对象集比DataAdapter.Fill填充到DataSet效率要高!DataAdapter.Fill内部工作原理没有去了解,但对象集是强类型的在数据转换存在拆箱,而DataSet不是强类型的按道理是填充DataSet在效率上占优越,但测试结果确相反!
测试代码如下(获取所有订单记录830条):
System.IO.StreamWriter write = new System.IO.StreamWriter(@"c:\testReader.txt");
Console.SetOut(write);
using(System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection("data source=.;initial catalog=northwind;user id=sa;pwd=;"))
{
 XSF.XUtils.XCounter counter = new XSF.XUtils.XCounter();
 System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
 cmd.CommandText ="select * from Orders";
 cmd.Connection = conn;
 conn.Open();
 for(int i =0;i<20;i++)
 {
  counter.Start();
  using(System.Data.IDataReader reader = cmd.ExecuteReader())
  {
   System.Collections.ArrayList list = new System.Collections.ArrayList();
   counter.Start();
   while(reader.Read())
   {
    Example.Entitys.OrdersOjb order = new Example.Entitys.OrdersOjb();
    order.LoadInfo(reader);
    list.Add(reader);
   }
   counter.Stop();
   Console.Write(" Orders:"+counter.Duration.ToString("0.000000000000000000000000000"+"\r\n"));
  }
  counter.Stop();
  System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(cmd);
  System.Data.DataSet myDS = new System.Data.DataSet();
  counter.Start();
  da.Fill(myDS);
  counter.Stop();
  Console.Write("DataSet:"+counter.Duration.ToString("0.000000000000000000000000000"+"\r\n\r\n"));
 }
    
}
write.Close();

表对应的映射对象
[Serializable]
public class OrdersOjb
{
 ...
 ...
 public  void LoadInfo(System.Data.IDataReader pDataReader)
 {
   
  if( pDataReader[0] != DBNull.Value)
  {
   this.OrderID= (Int32)pDataReader[0];
  }
  if( pDataReader[1] != DBNull.Value)
  {
   this.CustomerID= (String)pDataReader[1];
  }
  if( pDataReader[2] != DBNull.Value)
  {
   this.EmployeeID= (Int32)pDataReader[2];
  }
  if( pDataReader[3] != DBNull.Value)
  {
   this.OrderDate= (DateTime)pDataReader[3];
  }
  if(pDataReader[4] != DBNull.Value)
  {
   this.RequiredDate= (DateTime)pDataReader[4];
  }
  if(pDataReader[5] != DBNull.Value)
  {
   this.ShippedDate= (DateTime)pDataReader[5];
  }
  if( pDataReader[6] != DBNull.Value)
  {
   this.ShipVia= (Int32)pDataReader[6];
  }
  if( pDataReader[7] != DBNull.Value)
  {
   this.Freight= (Decimal)pDataReader[7];
  }
  if( pDataReader[8] != DBNull.Value)
  {
   this.ShipName= (String)pDataReader[8];
  }
  if( pDataReader[9] != DBNull.Value)
  {
   this.ShipAddress= (String)pDataReader[9];
  }
  if( pDataReader[10] != DBNull.Value)
  {
   this.ShipCity= (String)pDataReader[10];
  }
  if( pDataReader[11] != DBNull.Value)
  {
   this.ShipRegion= (String)pDataReader[11];
  }
  if( pDataReader[12] != DBNull.Value)
  {
   this.ShipPostalCode= (String)pDataReader[12];
  }
  if( pDataReader[13] != DBNull.Value)
  {
   this.ShipCountry= (String)pDataReader[13];
  }
   
 }
}
在映射对象中记获取DataReader时并没有用到字段名而是用索引,因为在测试时用索引获取比用键值获取大概快(2-3微秒),就是这一点效率的差别把整个情况扭转了(效率由原来慢大概50%变成快大概25%).
测试的结果:
 Orders:0.055864642014557700000000000
DataSet:0.110196687009103000000000000

 Orders:0.023227253743143300000000000
DataSet:0.020698999453841200000000000

 Orders:0.016390910017893300000000000
DataSet:0.023404929956181600000000000

 Orders:0.017637995890539200000000000
DataSet:0.025213819074770700000000000

 Orders:0.017227887901954000000000000
DataSet:0.024791977751362300000000000

 Orders:0.017724040345909900000000000
DataSet:0.022490009205080500000000000

 Orders:0.023765031589210400000000000
DataSet:0.021654986876823700000000000

 Orders:0.015963760757303000000000000
DataSet:0.021302707467010500000000000

 Orders:0.015803405181384800000000000
DataSet:0.020940929643292700000000000

 Orders:0.015981081394423000000000000
DataSet:0.020426059736642500000000000

 Orders:0.015780217876853100000000000
DataSet:0.024939482531997800000000000

 Orders:0.015689982944759700000000000
DataSet:0.020697043898037300000000000

 Orders:0.015734681363134100000000000
DataSet:0.021563913849385900000000000

 Orders:0.026096892202780000000000000
DataSet:0.020594516900891000000000000

 Orders:0.015682998816888700000000000
DataSet:0.020990656633734200000000000

 Orders:0.015992255999016600000000000
DataSet:0.021358021759748800000000000

 Orders:0.016322465564757500000000000
DataSet:0.020486961331677600000000000

 Orders:0.015694173421482300000000000
DataSet:0.028225933742975700000000000

 Orders:0.015794744862824700000000000
DataSet:0.022132701223200200000000000

 Orders:0.015866821062453500000000000
DataSet:0.020778059781340900000000000

    不过填充对象集就缺少了很多DataSet的功能.针对每个映射对象来编写获取信息方法也是一个很大的工作量,不过可以利用CodeDom在运行时动太生成操作对象来代替相关的工作量(CodeDom应用描述:http://henryfan.cnblogs.com/archive/2005/11/28/286036.html)。

posted on 2005-11-29 14:17  henry  阅读(2439)  评论(2编辑  收藏  举报

导航