C ++迭代器和循环优化
我看到很多看起来像这样的c ++代码:
for( const_iterator it = list.begin(),
const_iterator ite = list.end();
it != ite; ++it)
与更简洁的版本相反:
for( const_iterator it = list.begin();
it != list.end(); ++it)
这两个公约的速度会有什么不同? 天真的第一个会稍微快一点,因为list.end()只被调用一次。 但是因为迭代器是const的,所以编译器似乎会将这个测试从循环中拉出来,为两者产生等效的装配。
我只是提到记录,C ++标准要求在任何容器类型(无论是vector
, list
, map
等)上调用begin()
和end()
都只需要一定的时间 。 实际上,如果在优化开启的情况下进行编译,这些调用几乎肯定会内联到单个指针比较。
请注意,此保证书并不一定持有额外的供应商提供的“容器”,实际上不服从的是标准的(例如单链表的第23章中规定了容器的正式要求slist
)。
两个版本虽然不一样。 在第二个版本中,它每次都会比较迭代器和list.end()
,以及list.end()
在循环过程中的计算结果。 现在当然,你不能修改list
通过为const_iterator it
; 但是没有任何东西阻止循环内的代码直接调用list
方法并对其进行变异,这可能(取决于哪种数据结构list
)更改结束迭代器。 因此,在某些情况下,事先存储结束迭代器可能不正确,因为在您达到它时,可能不再是正确的结束迭代器。
第一个可能几乎总是会更快,但如果您认为这会有所作为,请始终首先查看哪个更快,更快。
在这两种情况下,编译器都可能内联调用end()
,但如果end()
足够复杂,它可能会选择不内联它。 然而,关键的优化是编译器是否可以执行循环不变的代码运动。 我认为在大多数情况下,编译器不能确定end()
的值在循环迭代过程中不会改变,在这种情况下,除了在每次迭代之后调用end()
别无选择。