如果我有函数调用在这样的循环状态:函数调用for循环条件?
for (auto it = s.begin(); it != s.end(), ++it) {}
叫在每次迭代?我希望是的。编译器是否允许优化它呢?目前的编译器是否足够聪明以做到这一点?或者我更好地使用类似以下的东西:
for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {}
?
如果我有函数调用在这样的循环状态:函数调用for循环条件?
for (auto it = s.begin(); it != s.end(), ++it) {}
叫在每次迭代?我希望是的。编译器是否允许优化它呢?目前的编译器是否足够聪明以做到这一点?或者我更好地使用类似以下的东西:
for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {}
?
是的,程序必须在每次迭代中调用第二个表达it != s.end()
。我认为编译器可以在某些情况下优化它。
无论如何,不要编译器的工作。如果它可以被优化,编译器就有很大的机会做到这一点,并且无论如何这个调用没有显着的性能影响。
如果情况允许,你应该使用基于for循环的范围:
for (auto& i : s) {
// instructions
}
这样,编译器有更多的机会来优化你的代码,它是更容易阅读。
如果你想了解一下编译器可以优化多少东西的例子,看看这个! http://ridiculousfish.com/blog/posts/will-it-optimize.html
我通常会使用它,但实际上我需要操纵迭代器,所以经典的foreach循环对我来说不起作用 – Paladin
啊,然后使用循环的经典。但是再次,编译器非常聪明。在这种情况下,不需要复杂的代码。 –
我编辑我的答案是更通用的,我只是添加了一个伟大的文章的链接。 –
在
for (auto it = s.begin(); it != s.end(), ++it)
s.begin()
只调用一次。
s.end()
和operator++()
(对于++it
)在循环的每次迭代中被调用。
编译器允许优化它吗?
根据编译器,实现和优化级别,编译器可以优化掉s.end()
的调用。如果能优化掉operator++()
的电话,我会感到惊讶。
当前的编译器足够聪明吗?
无法回答。
还是我更好地使用类似以下内容:
for (auto it = s.begin(), auto end = s.end(); it != end; ++it) {}
它不会伤害。但是,如果在循环中修改s
,则可能会出现问题。如果s
未在循环中修改,我会建议使用此方法。
是的,它在每次迭代中被正式调用。是的,目前的编译器可能会内联该函数,并且每次看到s.end()
返回相同的值(指针?)。
除非分析显示这是程序中的瓶颈(极不可能),否则不需要复杂的代码。
当您使用C++ 11时,请考虑使用基于范围的for循环来避免此问题。 –
@NeilKirk在我的情况下不可用,我实际上需要迭代器来做有趣的事情。 – Paladin
我个人使用第二种方法编写循环,然后我不必担心它。我不知道它在实践中有多重要或不重要。 –