5
  1. llvm在使用orgcc编译器时,以下两个代码块在生成的机器代码方面是否有区别?
  2. 这种优化什么时候真正值得,如果有的话?

未优化:

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在循环执行期间不会改变。

4

2 回答 2

3
  1. 你真的需要自己检查一下。我的猜测是发出的代码存在差异,但它可能取决于编译器和编译器选项,当然也可能取决于array.
  2. 几乎从来没有,假设array.count与“一些工作”相比,评估几乎总是微不足道的。但是,测量它的方法是使用分析器(或等效的)并观察程序运行时的哪一部分花费在该代码行上。如果分析器是准确的,那是您希望通过更改它获得的最大收益。

假设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,即使看到定义也可能没有意识到它的非零返回性很重要。

于 2012-10-10T10:30:13.680 回答
1

史蒂夫杰索普的答案是一个很好的答案。我只想补充:

就个人而言,我总是使用优化版本。这只是在我的一组良好实践中将每个常量组件从循环中删除。这不是很多工作,它使代码更干净。这不是“过早的优化”,也不会引入任何问题或权衡。它使调试更容易(步进)。它可能会使代码更快。所以这对我来说是理所当然的。

于 2012-10-10T13:29:21.803 回答