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

时间:2011-07-18 04:18:18

标签: 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和sort对1000万个随机数进行排序比其他任何一个快10倍。

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

1 个答案:

答案 0 :(得分:14)

我一直在研究list::sortsource code)有趣的GLibC实现,它似乎没有实现传统的合并排序算法(至少没有我曾经有过的算法)之前见过。)

基本上它的作用是:

  1. 创建一系列存储桶(共64个)。
  2. 删除列表的第一个元素,将其排序并与第一个(i=0)存储桶合并。
  3. 如果在合并之前,i存储桶不为空,请将i存储桶与i+1存储桶合并。
  4. 重复步骤3,直到我们与空桶合并。
  5. 重复步骤2和3,直到要排序的列表为空。
  6. 将所有剩余的非空桶合并在一起,从最小到最大。
  7. 小注意事项:将存储桶X与存储桶Y合并将删除存储桶X中的所有元素,并将其添加到存储桶Y,同时保持所有内容排序。另请注意,广告连播中的元素数量为02^i

    现在为什么这比传统的合并排序更快?好吧,我不能肯定地说,但这里有一些想到的事情:

    • 它从不遍历列表以找到中间点,这也使算法更加缓存友好。
    • 由于较早的存储桶较小并且使用频率较高,因此对merge的调用会减少对缓存的影响。
    • 编译器能够更好地优化此实现。需要比较生成的程序集以确保这一点。

    我很确定实施此算法的人员对其进行了彻底的测试,因此,如果您想要一个明确的答案,您可能需要在GCC邮件列表中询问。