查询与赋值并存
以下内容需要使用List(集合)和Dictionary(字典), 其中Dictionary大家较少接触,如果对其不熟悉,请先行参考:Dictionary
在技术支持的过程中,我遇到一个用户,他希望在第三列中标出第一列有而第二列无的数据 ,其中第一列和第二列为整数型:
我给出的代码为:
For Each
dr As DataRow In DataTables("表A").DataRows
随后我进行了测试,在数据为1万行,第三列无数据的时候,执行上述代码花费了整整234秒,显然这样的效率是让人难以接受的。
上面的代码并没有什么特别的地方,在遍历过程中找出符合条件的行,并给此行的某列赋值而已。
那么到底是查找出了问题,还是赋值出了问题,以至于运行效率如此之低呢?
为了找出原因,我分别测试了查询和赋值:
测试查询的代码:
Dim
v As Boolean测试赋值的代码:
For Each
dr As DataRow In DataTables("表A").DataRows出人意料的是,两段代码运行得都非常快,都在瞬间完成了。
那为什么第一段代码需要花费234秒?难道查询和赋值不能出现在同一个遍历语句中吗?
为此我改写了第一段代码,让查询和赋值分开进行,新的代码为:
Dim
lst1 As New List(of DataRow)
同样在数据为1万行,第三列无数据的时候,执行上述代码只花了0.8秒,比原来的234秒快了整整300倍,效率差距之大,令人瞠目。
原因应该找到了,为了验证我的想法,我打算对Compute方法进行测试,因为Compute在计算过程同样要进行查询。
于是我另外写了两段代码,这次不使用Find进行查询,而是使用Compute方法进行计算:
常规的代码,计算和赋值在同一个遍历语句:
Dim
v As Double估计效率更高的代码,计算和赋值分开进行:
Dim
Dic As new Dictionary(of DataRow, Integer)果不其然,经过测试,第二段比第一段同样快了整整300倍。
现在我总结一下,符合以下三个条件,会出现效率低下的情况:
1、用For语句遍历某个表。
2、遍历过程中会用Find或Select查询此表,或者用Compute方法统计此表。
3、遍历过程中会大量修改此表中某些行的值,被修改的行数越多,对于性能影响越大,如果被修改的行数很少,则几乎没有影响。
强调一下,上述三项中提到的表必须都是同一个表。
我们改写的代码之所以高效,
是因为改写后的代码使得上述2、3项不再出现在同一个遍历语句中,而是在不同的遍历语句中出现。