llvm
或gcc
编译器时,在生成的机器代码方面,以下两个代码块之间是否存在差异?未优化:
for (int i=0; i<array.count; i++) {
//do some work
}
优化
int count = array.count;
for (int i=0; i<count; i++) {
//do some work
}
编辑:我应该指出array
是不可变的,array.count
在循环执行期间不会改变。
答案 0 :(得分:3)
array
的定义。array.count
几乎总是微不足道的。但是,测量它的方法是使用分析器(或等效的)并观察程序运行时在该代码行中花费的比例。如果分析器是准确的,那么你可以通过更改它来获得 most 。假设array.count
非常慢,您碰巧知道将始终返回相同的结果,但编译器不知道这一点。然后可能值得手动提升它。 strlen
被用作示例。在实践中strlen
实际上实际慢的频率是多么有争议,但很容易制造出可能比他们需要的速度慢的例子:
char some_function(char a) {
return (a * 2 + 1) & 0x3F;
}
for (int i = 0; i < strlen(ptr); ++i) {
ptr[i] = some_function(ptr[i]); // faster than strlen for long enough strings.
}
你和我知道some_function
永远不会返回0,因此字符串的长度永远不会改变。编译器可能看不到some_function
的定义,即使它确实看到定义可能没有意识到它的非零返回很重要。
答案 1 :(得分:1)
史蒂夫杰索普的答案很好。我只想补充一下:
就个人而言,我总是使用优化版本。只是在我的一组良好实践中,从循环中删除每个常量组件。这不是很多工作,它使代码更清洁。这不是“过早优化”,也不会引起任何问题或权衡。它使调试更容易(步进)。它可能会使代码更快。所以这对我来说是明智的。