为什么std :: sort()比std :: make_heap()更快?

时间:2016-01-19 21:00:59

标签: c++ algorithm sorting c++11 vector

我的13721057中有std::vector<Sequence>个元素。我需要对这个向量进行排序并获取前25个元素。我想,既然你可以在O(N)中构建一个堆,那么弹出25个元素(每个都是O(logN))比在O(NlogN)中对整个向量进行排序必须更快。

然而,当我给代码计时:

clock_t tStart = clock();
sort(mostFrequent.begin(), mostFrequent.end(), greater<Sequence>());
printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);

VS

clock_t tStart = clock();
make_heap(mostFrequent.begin(), mostFrequent.end());
printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);

对整个矢量进行排序似乎要快得多。这是为什么?

2 个答案:

答案 0 :(得分:12)

这不是一个完整的答案,但要获得13721057中的前25个元素,最好使用partial_sort

如果您只需要第25个元素,那么nth_element

作为旁注。为了按排序顺序获取小于X的第一个元素,我将使用lambda auto mid = std::partition,然后std::sort(begin,mid)。可能有更好的方法。

答案 1 :(得分:9)

编辑:正如评论中所建议的那样,我也尝试使用预先排序的输入,在这种情况下,我 设法为我的“昂贵的复制”类型提供比make_heap更快的排序,但仅限于小幅度约5-10%。

无论我尝试什么,我都无法在Solaris或Linux(gcc 4.4)上重现您的结果。 make_heap总是花费大约1/3的时间。

  • 没有优化vs -O3只会改变总时间,而不会改变相对顺序。
  • 我使用了你确切的物品数量。
  • 首先尝试对int进行排序,然后再对更大的“昂贵复制”类进行排序。
  • 猜到了你正在使用的内容。
  • 在printf外移动了计时调用,以确保它们始终正确排序。

我认为这种差异的实际原因是你的<>运算符的复杂程度不同,或者复制你的对象相对于我的方式比较它有点昂贵测试无法复制。