为什么 std::sort() 比 std::make_heap() 快
Why is std::sort() faster than std::make_heap()?
我的std::vector<Sequence>
中有13721057
元素。我需要对这个向量进行排序并抓取前 25 个元素。我想,既然你可以在O(N)
中构建一个堆,那么弹出 25 个元素(每个元素都是O(logN)
)一定比在 O(NlogN)
中对整个向量进行排序更快。
但是,当我对代码进行计时时:
clock_t tStart = clock();
sort(mostFrequent.begin(), mostFrequent.end(), greater<Sequence>());
printf("Time taken: %.2fsn", (double)(clock() - tStart)/CLOCKS_PER_SEC);
与。
clock_t tStart = clock();
make_heap(mostFrequent.begin(), mostFrequent.end());
printf("Time taken: %.2fsn", (double)(clock() - tStart)/CLOCKS_PER_SEC);
对整个向量进行排序似乎要快得多。这是为什么呢?
这不是
一个完整的答案,但要从13721057中获取前 25 个元素,您最好使用 partial_sort
.
如果您只需要第 25 个元素,则nth_element
.
作为旁注。为了按排序顺序获取小于 X 的第一个元素,我会用 lambda 做auto mid = std::partition
,然后std::sort(begin,mid)
.可能有更好的方法。
编辑:正如评论中所建议的,我也尝试使用预排序的输入,在这种情况下,我确实设法比make_heap更快地进行排序,对于我的"复制成本高昂"类型,但只有 5-10% 左右的一小部分优势。
无论我尝试什么,我都无法在 Solaris 或 Linux (gcc 4.4) 上重现您的结果。 make_heap
总是以花费时间的 1/3 的数量出现。
- 无优化与 -O3 仅更改总时间,而不更改相对顺序。
- 我用了你的确切数量的物品。
- 首先尝试对
int
进行排序,然后尝试对更大的"复制成本"类进行排序。 - 猜猜你正在使用什么。
- 将定时调用移到 printf 之外,以确保它们始终正确排序。
我假设这种差异的实际原因是您的<
运算符和>
运算符的复杂性不同,或者相对于以我的测试无法复制的方式比较对象而言,复制对象在某种程度上是昂贵的。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 当为可变性配置时,boost::heap::d_ary_heap 保留的额外 std::list 的目的是什么?
- C 将HEAP对象插入std ::用insert()插入映射,而另一个则存在删除新的对象
- 如何从 std::heap 弹出最小元素
- boost::heap::priority_queue与std::priority_queue的比较器