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