在循环条件下重复评估表达式是否效率低下?

时间:2014-07-03 15:57:57

标签: c++

作为初学者,我经常看到包含函数调用和一些计算密集型表达式的循环条件,如下所示(例如来自C ++ primer,loop语句):

for(int *beg = begin(array); beg != end(array); ++beg) ;

我担心的是: 由于在每次迭代中检查条件,因此评估条件内部的表达式(这里运行end()函数)是否成本高昂?

2 个答案:

答案 0 :(得分:9)

首先,这可能实际上没有可测量的性能影响:如果循环体需要花费几倍的时间(对于普通代码来说很常见),或者整个循环不是瓶颈,那么循环条件的任何优化都会被浪费掉。

其次,end()的常规实现是内联的完美候选者。一旦它内联,由于end()必须没有副作用,迭代器结构受循环不变代码运动的影响。在这两次转换之后,"手动优化"实际上没有区别。版本,为程序员付出额外的努力。

第三,即使第二点不适用,对于大多数代码来说,对于更简洁的代码来说,它的价格很小,尤其适用于初学者。使优化描述为上述微不足道的相同原因也使得人类应用相同的转换变得微不足道,如果需要出现

答案 1 :(得分:0)

因为书籍是教学的,所以可读性比性能更重要。如果没有必要弄清楚优化技巧,初学者更容易掌握算法原理!

在现实生活中,这也是有道理的:结束条件往往是复杂的,并受每次迭代的影响。因此,使结束条件可理解并隐藏实现细节更安全,更可维护。

如果表现非常重要,首先要考虑B.Kernighan的陈述:"不要让代码更快,但要找到更好的算法"

对于非常简单的时间关键循环,可能值得查看事实。你编写循环的方式很重要。这里有一些关于在字符串中搜索的巨大迭代的基准测试:

  • 传统迭代器方法每次检查.end():14秒
  • 在变量循环开始时缓存.end():10秒,好30%!
  • 使用counter& index,每次检查.size():860 ms
  • 从最后开始计数到0:670毫秒,好22%!
  • 使用指向c_str()的指针,将整个内容减少到... 63毫秒!

但请记住,最好的反对者是你的编译器。打开优化后,时间为1274毫秒,677毫秒,42毫秒,42毫秒和33毫秒,即从50%到92%更好!!