今天做了一个测试,用DataTable获取数据然后转Json和实体类,以及用DataReader获取数据然后转Json和实体类,出现了下面的一个情况: (1)从数据库获取的数据转换成实体类时,用DataTable比用DataReader转实体快 (2)从数据库获取的数据转换成JSON字符串时,用DataReader比用DataTable转JSON字符串快 从DataReader和DataTable的性质看, DataReader是一条一条读取,再转JSON的时候直接转换, 而DataTable是读取所有数据然后缓存在内存,在转JSON格式的时候在遍历一遍去转, 所以才会出现上面的(2)这种情况,但是为什么又会出现(1)这种情况呢,求大神帮忙指点下 测试环境: (1)相同的电脑 (2)测试数据是10万条到100万条数据 (3)测试了上百组数据基本都是上面的结果,不存在偶然性 下面附上转实体的时候的代码: 图1是DataReader转实体类的代码: 图2是DataTable转实体类的代码: 你所谓的 getdatatable 是什么呢?完全看不出来其实质,所以无法判断。
而且从你贴出的代码,也无法判断你是在哪一个代码范畴去统计时间的,以及如何(用什么具体代码)去统计时间的。 对于任何.net程序来说,第一次加载一个Assembly时都可能有很长的加载时间。第一次访问Assembly跟以后(第二次以后)访问时间相比,可能会相差20倍以上时间。因此任何测试都要考虑这点,你放在前边首先测试的代码,其第一组数据应该删除掉。或者说,把最低、最高值都应该删除掉。 如过你所谓的 GetDataTable 中使用到了 DataTable 标配的 DbDataAdapter,如果你看看其源代码就会发现,它正是一行一行地调用 DbDataReader 来填充 DataTable的。因此如果你发现人家直接生成的 DataTable 比你写的 DbDataReader.Read 方式还快,那么你应该检查一下自己的代码。具体来说,本来 DataTable 比 DataReader.Read 慢,但是你从 DataReader读取字段的方式、又慢于从 DataRow 读取字段的方式。 最后,但是其实是最关键的,我非常反对滥用反射。不仅仅是你的 GetProperties() 方法该不该循环许多次的问题,也不仅仅是 Property.SetValue(....) 方法应该先缓存为 delegate 然后直接调用委托(而不是一次次地去从 Property 反射调用 SetValue 方法)的问题,我是直接反对滥用反射的! 除非万不得已,否则我们可以直接写代码 C# code?
也就是说直接用比较明确的、不含反射的方式,产生强类型的对象集合就好了。上面少了 conn.Open()语句,请自己加上。 对于最后这几行代码,许多人还会设计一个 SqlHelper 类库来简化它。例如可以在 SqlHelper 中有这样的方法 C# code?
或者跨(不同类型)数据库的通用方法 C# code?
总之,不反射。 如何写 SQLHelper 是另外一个话题了,我的重点是在与你玩儿“反射”上。在你的这个测试中,哪里是测试 DataTable 和 DataReader.Read 呢?
由于巨大的循环反射具有严重的性能问题,那么原本要比较的性能差距就应该约等于0了(不重要了)。优于你并没有给出实际的测试结果数值,我不知道你的比较结果(时间差)是相当于一根火柴那么值钱、还是相当于一根眼睫毛那么值钱。但是总的来说,DataTable或者 DataReade.Read 的差距基本上可以忽略,而是要从更大的原则来优化自己日常写的代码。 |
|