【问题标题】:Fast stable sort for small arrays (under 32 or 64 elements)小型数组(32 或 64 个元素以下)的快速稳定排序
【发布时间】:2010-11-19 14:07:39
【问题描述】:

常识说,对于足够小的数组,插入排序是最好的。例如,Timsort 对最多 64 个元素的数组使用(二进制)插入排序;来自Wikipedia

一些分而治之的算法,例如快速排序和归并排序,通过递归地将列表划分为较小的子列表,然后对这些子列表进行排序。这些算法在实践中的一个有用优化是使用插入排序对小的子列表进行排序,因为插入排序优于这些更复杂的算法。插入排序具有优势的列表大小因环境和实现而异,但通常在 8 到 20 个元素之间。

这真的正确吗?有没有更好的选择?

如果这很大程度上取决于平台,我对 .NET 最感兴趣。

【问题讨论】:

    标签: .net performance arrays sorting


    【解决方案1】:

    是的,这是我在算法课中学到的,这也是排序在 C++ STL 中的实现方式。来自维基百科:

    2000 年 6 月的 SGI C++ 标准 模板库 stl_algo.h 不稳定排序使用的实现 Musser introsort 方法与 切换到堆排序的递归深度 作为参数传递,中位数为 3 枢轴选择和塞奇威克 最后的插入排序通过。元素 切换到简单的门槛 插入排序是 16。

    我去年做了一些非正式的性能测试,C++ STL std::sort 的速度大约是 .NET 中的 Array.Sort 的两倍。我不知道 .NET Array.Sort 是如何实现的,但是在 .NET 中,对数组的访问需要进行边界检查,这与 C++ 不同,这在很大程度上可以解释性能差异。

    【讨论】:

      【解决方案2】:

      我发现这实际上取决于比较函数需要做多少工作。就像我间接对工作表的行进行排序,每次比较都涉及获取一行,然后比较可能的几列,可能混合数字和字符串比较,它可能会变慢。

      另一方面,如果数组的长度很短,则取决于每秒需要对它进行多少次排序,因为即使它与可能的速度相比相对较慢,您也可能永远不会注意到区别。

      如果我有任何疑问,我只需编写一个合并排序代码并继续。我在 qsort 不稳定并且有时需要很长时间的情况下有过糟糕的经历。手工编码的归并排序简单、可靠且足够快。

      【讨论】:

        【解决方案3】:

        对于小列表,没有比插入排序更快的 O(n log n) 算法了。但是,有一些 O(n^2) 算法确实存在竞争。值得注意的是,选择排序不是其中之一,尽管它在交换和移动昂贵的罕见情况下很好。冒泡排序和变体也很糟糕。

        网络排序:一种排序算法,始终稳定,没有分支。总体而言,它的规格很糟糕,但没有分支意味着在最小的列表中表现出色。基本情况是:if(a<b) swap(a,b);

        批量插入排序:在每个循环中,对 2-4 个元素进行排序,然后将它们插入在一起。这减少了移动次数,比较长的列表可以减少 25% 到 37%。总体效果是对大小范围为 16 到 64 的列表进行了优化。

        【讨论】:

          【解决方案4】:

          因为 .NET 是一种不能编译为原始机器码的语言。我想说调用 API 函数(它确实使用本机代码)可能是最快的方法

          【讨论】:

          • 我想知道在 c++ 和 c# 上对 40 个元素的数组进行排序有什么区别 - 然后我想知道它是否真的很重要。
          • @sirrocco 我已经在考虑它并研究howto的混合模式等'以避免api调用的开销或最小化..
          猜你喜欢
          • 2015-06-02
          • 1970-01-01
          • 1970-01-01
          • 2017-05-13
          • 2017-04-02
          • 1970-01-01
          • 2021-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多