C# DataTable 循环性能比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-07-31 15:57:44  来源:igfitidea点击:

DataTable Loop Performance Comparison

提问by GateKiller

Which of the following has the best performance?

以下哪个性能最好?

I have seen method two implemented in JavaScript with huge performance gains, however, I was unable to measure any gain in C# and was wondering if the compiler already does method 2 even when written like method 1.

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

The theory behind method 2 is that the code doesn't have to access DataTable.Rows.Count on every iteration, it can simple access the int c.

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

Method 1

方法一

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

Method 2

方法二

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

采纳答案by Lasse V. Karlsen

No, it can't do that since there is no way to express constant over timefor a value.

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

If the compiler should be able to do that, there would have to be a guarantee from the code returning the value that the value is constant, and for the duration of the loop won't change.

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

But, in this case, you're free to add new rows to the data table as part of your loop, and thus it's up to you to make that guarantee, in the way you have done it.

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

So in short, the compiler will not do that optimization if the end-index is anything other than a variable.

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

In the case of a variable, where the compiler can just look at the loop-code and see that this particular variable is not changed, it might do that and load the value into a register before starting the loop, but any performance gain from this would most likely be negligible, unless your loop body is empty.

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

Conclusion: If you know, or is willing to accept, that the end loop index is constant for the duration of the loop, place it into a variable.

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



Edit:Re-read your post, and yes, you might see negligible performance gains for your two cases as well, because the JITter optimizes the code. The JITter might optimize your end-index read into a direct access to the variable inside the data table that contains the row count, and a memory read isn't all that expensive anyway. If, on the other hand, reading that property was a very expensive operation, you'd see a more noticable difference.

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