【发布时间】:2013-10-14 03:35:44
【问题描述】:
一般来说,在两个 STL 容器迭代器之间进行相等比较的性能成本是多少?我只是在谈论定义的操作;也就是说,比较两个引用同一个对象的迭代器。
我的具体用例是我有一个std::map,它可能包含非常大的元素、很多元素,或两者兼而有之。如果这样一个映射上的两个迭代器之间的相等比较具有我不知道的隐藏惩罚,它可能会影响我的代码的性能。
【问题讨论】:
标签: c++ performance c++11 stl iterator
一般来说,在两个 STL 容器迭代器之间进行相等比较的性能成本是多少?我只是在谈论定义的操作;也就是说,比较两个引用同一个对象的迭代器。
我的具体用例是我有一个std::map,它可能包含非常大的元素、很多元素,或两者兼而有之。如果这样一个映射上的两个迭代器之间的相等比较具有我不知道的隐藏惩罚,它可能会影响我的代码的性能。
【问题讨论】:
标签: c++ performance c++11 stl iterator
通常,比较两个迭代器的性能取决于 STL 的实现。
然而,关于时间复杂度,C++ 标准规定了输入迭代器(以及因此前向迭代器、双向迭代器和随机访问迭代器)的比较需要摊销常数时间的限制。特别是对于std::map<std::string, int>,这意味着它的迭代器不能通过比较键是否相等来进行比较,因为这将与键的长度成线性关系。
【讨论】:
draft Standard 声明迭代器操作是amortized constant time
24.2.1 一般 [iterator.requirements.general]
8 所有类别的迭代器只需要那些函数 在恒定时间内(摊销)对于给定类别是可实现的。 因此,迭代器的需求表没有 复杂性列。
如果查看迭代器操作的签名,则没有参数或返回类型对应于底层元素T 本身,只有T* 和T& 是必需的。即使operator== 也不必直接比较两个任意大的元素T 本身。
但是,这并没有给出迭代器操作的硬实时上限。特别是,迭代器可以执行very costly bounds checking,但这些调试模式安全防护通常可以在发布版本中省略。
【讨论】:
大多数 STL 容器operator==() 只是原始指针比较。除非用于边界检查,否则这是没有意义的。此外,如果您正在比较来自不同容器的迭代器 - 这是未定义的行为。
如果您覆盖此运算符或使用外部比较函数,则性能取决于您要比较的对象有多大。
可能我把你的问题弄错了,“迭代器比较”是什么意思以及你的用例是什么并不是 100% 清楚。
【讨论】: