是否值得在for循环中预先计算条件?

时间:2012-10-10 10:09:18

标签: objective-c c

  1. 使用llvmgcc编译器时,在生成的机器代码方面,以下两个代码块之间是否存在差异?
  2. 这个优化什么时候真的值得,如果有的话?
  3. 未优化:

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

2 个答案:

答案 0 :(得分:3)

  1. 你真的需要亲自检查一下。我的猜测是 在发出的代码中存在差异,但它可能依赖于编译器和编译器选项,它当然可能取决于array的定义。
  2. 几乎从不,假设与“某些工作”相比,评估array.count几乎总是微不足道的。但是,测量它的方法是使用分析器(或等效的)并观察程序运行时在该代码行中花费的比例。如果分析器是准确的,那么你可以通过更改它来获得 most
  3. 假设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)

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

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