题
以下哪项的性能最好?
我已经看到在 JavaScript 中实现的方法二具有巨大的性能提升,但是,我无法测量 C# 中的任何提升,并且想知道即使像方法 1 那样编写,编译器是否已经执行了方法 2。
方法 2 背后的理论是代码不必在每次迭代时访问 DataTable.Rows.Count,它可以简单地访问 int c。
方法一
for (int i = 0; i < DataTable.Rows.Count; i++) {
// Do Something
}
方法2
for (int i = 0, c = DataTable.Rows.Count; i < c; i++) {
// Do Something
}
解决方案
不,它不能这样做,因为没有办法表达 随时间恒定 为了一个值。
如果编译器能够做到这一点,则返回值的代码必须保证该值是常量,并且在循环期间不会改变。
但是,在这种情况下,作为循环的一部分,您可以自由地将新行添加到数据表中,因此由您来以您所做的方式做出保证。
简而言之,如果结束索引不是变量,则编译器不会进行优化。
对于变量,编译器只需查看循环代码并查看该特定变量未更改,它可能会这样做并在启动循环之前将值加载到寄存器中,但由此带来的任何性能增益很可能是可以忽略不计的,除非你的循环体是空的。
结论:如果您知道或愿意接受结束循环索引在循环期间保持不变,请将其放入变量中。
编辑: 重新阅读您的文章,是的,您可能会发现这两种情况的性能增益也可以忽略不计,因为 JITter 优化了代码。JITter 可能会将最终索引读取优化为对包含行计数的数据表内的变量的直接访问,而且内存读取无论如何也不是那么昂贵。另一方面,如果读取该属性是一项非常昂贵的操作,您会看到更明显的差异。
不隶属于 StackOverflow