在循环外计算map.end()的优势

Advantage of computing map.end() outside the loop

本文关键字:end 循环 计算 map      更新时间:2023-10-16

我最近遇到了以下代码。

std::map<int, int> m;
// insert into the map
std::map<int, int>::iterator endOfMap = m.end();
for(std::map<int, int>::iterator itr = m.begin(); itr != endOfMap; ++itr) {
}

事先计算endOfMap比下面的有什么优势吗?

for(std::map<int, int>::iterator itr = m.begin(); itr != m.end(); ++itr) 

注意:
我看到的代码是字符串到自定义对象的映射,包含数百万个元素。

由于您不知道map的实现,因此可以假设在循环之前进行赋值可以节省每次通过循环调用end()的开销。

但是开销是多少?我们已经知道end()是隐式内联的,因为它是一个模板函数;如果代码足够简单,编译器很可能会消除函数调用开销。C++标准保证end()是一个O(1)函数,这意味着它可能不会太复杂。如果end()只是在没有其他计算的情况下返回对象的一个成员,那么将其复制到局部变量可能完全没有节省!

另一方面,这是一个不需要花费任何成本的优化的主要例子。如果你养成了对你写的每个for循环都这样做的习惯,这不会有什么坏处,偶尔也会有所帮助。我甚至看到了在for循环的第一段中完成的赋值,而不是在它自己的行上。

预先计算endOfMap比下面的有什么优势吗?

我能看到的唯一优势是在循环的每次迭代中调用std::map::end()的成本降低。差别很可能很小。你只能通过迭代一个包含大量元素的map来找到它。即使std::map::end()的调用成本由O(1)的标准保证,但调用它数百万次可能会给函数/程序增加明显的成本。

它在每次迭代时为您节省了一个函数调用,但考虑到map.end()是一个非常轻量级的方法,除非您每秒调用此函数一百万次,否则您不会看到任何区别。