【问题标题】:C++ Time Taken in Map Access and Iteration地图访问和迭代中的 C++ 时间
【发布时间】:2016-03-02 12:43:37
【问题描述】:

我正在使用 gprof 分析代码,我发现 -> 运算符会消耗大量时间。

这是地图的示例定义。

map<int, vector<int> > myMap;

我有一个迭代器,

map<int, vector<int> >::iterator it;

我经常运行这样的循环:

for(it = myMap.begin(), it != myMap.end(); it++) {
   //Do stuff
}

这是来自分析的数据

Function:
std::_Rb_tree_iterator<std::pair<int const, std::vector<ClassType*, std::allocator<ClassType*> > > >::operator->() const
Time Consumed:
20.18%
Number of Times function is called:
15285739415

Function:
std::_Rb_tree_iterator<std::pair<int const, std::vector<ClassType*, std::allocator<ClassType*> > > >::operator++(int)
Time Consumed:
2.90%
Number of Times function is called:
3825378111

据我了解,++ 运算符计算占用O(log(n)) 的下一个元素,-> 给出应该占用O(1) 时间的元素。 即使 -> 运算符被称为多于 ++ 运算符,我认为它不应该消耗那么多时间。 ++ 不应该比-&gt; 操作符消耗更多的时间吗?

【问题讨论】:

  • 您是否在进行优化编译?没有优化的分析根本没有代表性。
  • 还要注意 operator-> 的调用频率比 operator++ 高 4 倍。这是故意的吗?此外,该标准要求迭代器上的所有操作均摊销持续时间([iterator.requirements.general] P8)。因此增量也是 O(1)
  • 我正在编译没有优化。我将尝试使用优化进行编译。 -> 被称为超过 ++,因为我更频繁地访问内存。如果 ++ 是 O(1),那么哪个运算符计算下一个节点?看->的函数调用,我不认为->计算下一个节点。
  • ++ 找到下一个节点。但它不会再次遍历树就这样做了(它只需要先上然后再下到下一个孩子)。这给出了摊销的常数时间。
  • 哦!好的。知道了。谢谢!

标签: c++ c++11 dictionary operators


【解决方案1】:

内存访问(-&gt; 运算符)通常比算术运算(++ 运算符)慢得多。

这是因为搜索数据需要时间,从最低级别的缓存(最靠近寄存器)一直到硬盘驱动器中的可能页面。正如您所料,您离寄存器越远,这将花费相当多的时间。

然而,算术运算可能不需要涉及内存访问。如果算术运算所涉及的数据可以放入寄存器,那么即使是最底层的缓存也不需要访问。

这里是good article,关于缓存一致性/空间局部性如何影响您的应用程序的速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-11
    • 2017-08-22
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 2014-07-26
    • 1970-01-01
    相关资源
    最近更新 更多