linux - 是什么让 gcc std::list 排序实现如此之快?

标签 linux algorithm g++ stdlist

我有一个链表实现,我正在试验 Mergesort 和 QuickSort 算法。

我不明白的是为什么std::list中的排序操作这么快。 查看 linux 下的 std::list ,它似乎也是链表,而不是基于数组的列表。

我在这里尝试的合并排序与 Dave Gamble 的版本几乎相同: Merge Sort a Linked List

另外,我想我会尝试基于这段代码的简单快速排序: http://www.flipcode.com/archives/Quick_Sort_On_Linked_List.shtml

令人惊讶的是,使用 std::list 对 1000 万个随机数进行排序并排序比其他任何一个快大约 10 倍。

对于那些提问的人,是的,我需要为这个项目使用我自己的列表类。

最佳答案

我一直在查看有趣的 GLibC 实现 list::sort ( source code ) 而且它似乎没有实现传统的合并排序算法(至少我以前从未见过)。

基本上它的作用是:

  1. 创建一系列存储桶(总共 64 个)。
  2. 删除列表的第一个元素进行排序并将其与第一个(i=0)桶合并。
  3. 如果在合并之前,第i桶不为空,则将第i桶与第i+1桶合并.
  4. 重复第 3 步,直到我们与一个空桶合并。
  5. 重复步骤 2 和 3,直到要排序的列表为空。
  6. 将所有剩余的非空桶从小到大合并在一起。

小提示:将桶 X 与桶 Y 合并将删除桶 X 中的所有元素并将它们添加到桶 Y 同时保持一切有序。另请注意,存储桶中的元素数量为 02^i

为什么这比传统的归并排序更快?好吧,我不能肯定地说,但我想到了以下几点:

  • 它从不遍历列表来寻找中点,这也使算法对缓存更友好。
  • 由于较早的存储桶较小且使用频率较高,因此调用 merge 会降低缓存垃圾的频率。
  • 编译器能够更好地优化这个实现。需要比较生成的程序集才能确定这一点。

我很确定实现该算法的人已经对其进行了彻底的测试,因此如果您想要一个明确的答案,您可能必须在 GCC 邮件列表上询问。

关于linux - 是什么让 gcc std::list 排序实现如此之快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6728580/

相关文章:

c++ - UNIX C 编程

linux - "everything is a file"对于 Linux 来说有多准确?

c++ - 具有相同复制值的类型转换问题到新数组类型

algorithm - 形状内分布线的优化算法选择

algorithm - 队列平均 O(1) 入队和出队

c++ - 将 clang 构建的可执行文件与 g++-v6 构建的 boost 库链接时出错

json - MongoDB 配置文件格式

java - 运行 Kafka 性能流量时出现错误 "This server is not the leader for that topic-partition"

c++ - 什么决定了在 64 位机器上构建的 32 位库是否需要 x86_64 或 i386 依赖项?

c++ - 返回非静态本地对象时,选择复制构造函数而不是 move 构造函数