13

以下哪项表现最好?

我已经看到在 JavaScript 中实现的方法 2 具有巨大的性能提升,但是,我无法衡量 C# 中的任何收益,并且想知道编译器是否已经执行方法 2,即使像方法 1 那样编写也是如此。

方法 2 背后的理论是代码不必在每次迭代时访问 DataTable.Rows.Count,它可以简单地访问 int c。

方法一

for (int i = 0; i < DataTable.Rows.Count; i++) {
    // Do Something
}

方法二

for (int i = 0, c = DataTable.Rows.Count; i < c; i++) {
    // Do Something
}
4

1 回答 1

6

不,它不能这样做,因为没有办法表示一个值随时间的常数

如果编译器应该能够做到这一点,那么返回值的代码必须保证该值是常量,并且在循环期间不会改变。

但是,在这种情况下,作为循环的一部分,您可以自由地将新行添加到数据表中,因此您可以按照自己的方式做出保证。

所以简而言之,如果结束索引不是变量,编译器将不会进行优化。

在变量的情况下,编译器可以只查看循环代码并看到这个特定的变量没有改变,它可能会这样做并在开始循环之前将值加载到寄存器中,但是由此带来的任何性能提升除非您的循环体为空,否则很可能可以忽略不计。

结论:如果您知道或愿意接受,结束循环索引在循环期间是恒定的,请将其放入变量中。


编辑:重新阅读您的帖子,是的,您可能会看到两种情况下的性能提升也可以忽略不计,因为 JITter 优化了代码。JITter 可能会将您的最终索引读取优化为直接访问包含行数的数据表中的变量,并且内存读取无论如何也不是那么昂贵。另一方面,如果读取该属性是一项非常昂贵的操作,您会看到更显着的差异。

于 2008-08-07T10:09:58.703 回答