C++ std::set::insert,我能暗示多坏?
我正在做大量的C++ std::set::insert,我能暗示多坏?,c++,C++,我正在做大量的std::pair插入到std::set中,所花的时间比我想要的要长。当我编写代码时,我想如果它最终成为一个瓶颈,我会考虑使用insert的提示迭代器形式;好吧,现在它被分析了,它是一个瓶颈。所以我想使用迭代器提示 然而,我并不总是知道插入配对的好位置。我通常会按递增的集合顺序分批插入它们(在本例中,一个批次的大小约为总输入大小的0.01%,包括重复项),但插入一个批次时,我不知道下一个批次应从何处开始。如何使用提示?insert是否执行类似于从建议位置进行二进制搜索的操作?通常,
std::pair
插入到std::set
中,所花的时间比我想要的要长。当我编写代码时,我想如果它最终成为一个瓶颈,我会考虑使用insert的提示迭代器形式;好吧,现在它被分析了,它是一个瓶颈。所以我想使用迭代器提示
然而,我并不总是知道插入配对的好位置。我通常会按递增的集合顺序分批插入它们(在本例中,一个批次的大小约为总输入大小的0.01%,包括重复项),但插入一个批次时,我不知道下一个批次应从何处开始。如何使用提示?insert是否执行类似于从建议位置进行二进制搜索的操作?通常,使用错误提示会有多糟糕?我建议只阅读编译器阅读的内容:include的头文件。在我的系统(GNU libstdc++4.5.1)上,我可以阅读以下自解释文本:
/**
* @brief Attempts to insert an element into the %set.
* @param position An iterator that serves as a hint as to where the
* element should be inserted.
* @param x Element to be inserted.
* @return An iterator that points to the element with key of @a x (may
* or may not be the element passed in).
*
* This function is not concerned about whether the insertion took place,
* and thus does not return a boolean like the single-argument insert()
* does. Note that the first parameter is only a hint and can
* potentially improve the performance of the insertion process. A bad
* hint would cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
iterator
insert(iterator __position, const value_type& __x)
{ return _M_t._M_insert_unique_(__position, __x); }
外卖:
O(日志n)
如果提示是正确的,那么提示就是好的——插入的位置。例如,如果按顺序插入对象,则可以使用
如果提示不正确,则无效,您将得到一个非提示的插入。如果您检查文件
bits/stl_tree.h
(在GNU libstdc++),您将发现带有提示参数的\u M_insert_unique
成员函数在提示的左侧显示一个节点,然后在右侧显示一个节点,然后默认调用普通的插入例程
它调用键\u compare
至少一次(如果集合不是空的),最多三次。从一个节点到下一个或上一个节点是一个跟随指针的问题,因为(IIRC)std::set
和朋友都是
因此,错误提示的严重程度取决于比较例程,以及
std::set
的分配器是否在内存中关闭节点。如果在使用集合之前一次构建集合,则可以使用向量,并在使用集合之前对其进行排序。您可以在排序向量上使用二进制搜索
,下限
,上限
,以及相等范围
算法进行快速查找。您还可以使用merge
或inplace\u merge
组合已排序的向量,set\u difference
、set\u intersection
和set\u union
执行其他常见的集合操作。比我想要的长吗?我知道O(n)
,O(logn)
,甚至O(n^2)
。。。但是O(比我想要的长)
不在我的文本书中。嗯,事情也很少需要O(logn)
秒。。。但进行约200000次插入(重复)大约需要4秒钟。这对用户来说是一个明显的延迟,如果这是一个瓶颈,您可以使用unordered\u set
进行基准测试,我想缩短它。Boost或STL取决于您的编译器。嗯,因此,如果提示不完全正确,它可能会被完全忽略?您必须在这里阅读字里行间的内容。如果提示被证明是错误的,它可能会返回并立即调用未提示的版本-但这并没有明确说明。@carlpett:是的,可能。你的C++实现在理论上可以做一些更聪明的事情(不可能,但可能);如果您指定了实际的编译器和版本,可能会有人给出明确的答案。链接断开了,是吗?@doug65536看起来是这样。答案文本已编辑为指向回程机器:)