【问题标题】:Advantage of computing map.end() outside the loop在循环外计算 map.end() 的优势
【发布时间】:2017-01-30 02:44:46
【问题描述】:

我最近遇到了以下代码。

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) 

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

【问题讨论】:

  • 好吧,它们的计算速度可能会如此接近,但是让我们以第一个例子为例,第一个例子已经计算了函数调用并执行它需要的任何操作,以 endOfMap。终止条件中的第二个示例将多次调用 m.end() 函数,然后检查它们是否相等。而不是仅仅检查它们是否不相等而不是多次调用该函数。
  • 您在 for 循环迭代中谈论 O(end()) + O(equality checks) vs. O(equality checks)。
  • map 的数据内存分配带来的性能下降将超过循环外调用 end() 带来的任何改进!

标签: c++ performance stl iterator


【解决方案1】:

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

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

另一方面,这是一个无需花费任何成本的优化示例。如果您养成为编写的每个for 循环执行此操作的习惯,那么它不会受到伤害,并且偶尔会有所帮助。我什至看到在for 循环的第一段而不是在它自己的一行中完成了分配。

【讨论】:

  • 谢谢你:)。从下面@Alejandro 的评论中,我认为编译器无论如何都会对此进行优化?
  • 但是所有模板函数都内联吗?
  • @ThirupathiThangavel 是的,因为它们是在类声明中定义的。您会注意到模板函数的所有代码都是头文件的一部分;如果 .cpp 文件中有任何函数,则它们必须位于基类中。
【解决方案2】:

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

我可以看到的唯一优势是降低了在循环的每次迭代中调用std::map::end() 的成本。差异很可能会很小。您只能通过遍历其中包含大量元素的 map 来找到它。尽管标准保证调用std::map::end() 的成本为O(1),但调用它数百万次可能会显着增加函数/程序的成本。

【讨论】:

  • @songyuanyao 它并不总是 O(n) 恒定时间。底层实现可能有一个不断跟踪最后一个元素的指针。除非你知道它不会跟踪这一点,只是等到结束并遍历。
  • @OmidCompSCI 我的意思是std::map::end() 本身总是花费恒定的时间;这是标准要求的。
  • @songyuanyao 是的,但是地图是否会跟踪函数调用 m.end 之前的最后一个元素?如果是这样,那么定位最后一个元素只需 O(1)。那 m.end() 可能只是返回指向最后一个元素的指针?
  • @OmidCompSCI 这可能是一种实现方式,std::map 通常由红黑树实现。实现只需要保证标准要求。
  • 我想任何优化编译器都能够在循环外提升调用并将值保存在寄存器中,前提是编译器有足够的可见性来证明该值不会改变。 Here's an example
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2013-10-30
    • 1970-01-01
    • 2018-06-16
    相关资源
    最近更新 更多