Java和.NET:为什么默认情况下使用不同的排序算法?


19

只是想知道为什么,Java并且.NET Framework默认情况下使用不同的排序算法。

在Java中 ,默认情况下Array.Sort()使用合并排序算法,如Wikipedia.com所述

在Java中,Arrays.sort()方法根据数据类型使用合并排序或调整后的快速排序,当排序少于七个数组元素时,为了实现转换为插入排序的实现效率

在.NET Framework中, Array.Sort/List.Sort()使用“ 快速排序”作为默认排序算法(MSDN):

List.Sort()使用Array.Sort,后者使用QuickSort算法。此实现执行不稳定的排序;也就是说,如果两个元素相等,则可能不会保留其顺序。相反,稳定排序保留了元素相等的顺序。

通过查看出色的“算法比较”表,我们可以发现两种算法在最坏情况和内存使用情况方面的行为都大不相同:

在此处输入图片说明

这两个Java.NET是企业解决方案发展的巨大框架,既有嵌入式开发平台。那么为什么他们默认使用不同的排序算法,有什么想法呢?


1
有关这两种类型的比较的进一步讨论,请参见stackoverflow.com/q/680541/866022
yoozer8 2011年

Answers:


10

正如计算机本身具有确定性一样,计算机工程也不是一门精确的科学。给定相同问题域的两个人将进行分析,并开发出满足问题所有约束的两种不同解决方案。在一般情况下,根据经验确定其中哪一个“更好”可能很困难或不可能。

我的猜测是,.NET QuickSort位于MFC或Windows API中,并且可能继承自Windows的许多旧版本,在Windows的计算机中甚至都没有考虑过MergeSort的多用途优势。那天。(编辑:不是,尽管Microsoft开发人员一直以来都是QuickSort的狂热者,从MS-DOS以来的这种排序实现选择就证明了这一点)。

由于Java是从头开始设计为完全独立于平台的,因此Java无法使用任何特定于平台的实现,它采用了不同的方式。谁知道为什么MergeSort脱颖而出?我的大胆猜测是,与开发人员想出的其他实现相比,该实现赢得了某种性能竞争,或者就最佳情况和最坏情况而言,O(n)空间的MergeSort在纸上看起来都最好。 (MergeSort没有与QuickSort之类的元素选择相关的致命弱点,它的最佳情况是列表几乎排序,而这通常是QuickSort最糟糕的)。我怀疑最初考虑了多线程的好处,但是当前的实现很可能是多线程的。


1
List<T>.Sort.NET中的Java使用CLR中实现的本机方法(如果不使用自定义比较器),但不依赖于OS库。
2014年

1
@Keith-.NET不在任何事物之上,并且被设计为独立于平台的。您可以在这里看到实现:github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/…–
Robert MacLean

@RobertMacLean-“ .NET不在任何东西之上”并不是一个正确的陈述,尽管您已经证明所讨论的Sort函数完全是“托管”代码。.NET的大部分(包括加密支持,Windows桌面GUI库,Windows API互操作(包括进程和线程控制))均基于包括MFC在内的预先存在的非托管代码。他们只是必须如此。Windows本身在其代码库中只有一个非常小的.NET组件,其余部分不受管理
KeithS 2015年

微软开发人员仍然是QuickSort优于其他实现的忠实拥护者,因为QuickSort自MS-DOS以来一直是首选算法,这将影响他们使用此算法实现.NET排序的决定。
KeithS

老实说,这个答案太错了。
user9993

17

两家不同公司的不同开发团队就其框架和组件的常用案例得出了不同的结论,并决定相应地实施。

本质上,每家公司都进行了分析,查看了他们的客户基础,并据此做出了不同的决定。

您不能期望不同的公司和团队使用不同的假设和原始数据进行分析得出相同的结论。


5
甚至是相同的假设和原始数据。。。
Wyatt Barnett

是的,这可能只是习惯的习惯-微软习惯于使用(不稳定的)Quicksort,Java希望使用稳定类型...而合并排序是已知最快的稳定类型...
rogerdpack

12

这个问题有点过时了,因为Java现在使用Timsort(从Java 7开始)

在提到的特定算法中:

  • Quicksort在O(n ^ 2)的情况下具有不利的最坏情况性能,但更轻量/更少的内存消耗,因此在典型情况下可提供更好的性能。

  • Mergesort保证了O(n log n)的最坏情况下的性能,但是会带来更多的开销和内存需求。它还是自动稳定的(即,以相同的顺序维护相等的元素)。

Java设计师总体上似乎更加保守/专注于“正确的事情”,因此毫不奇怪的是,他们从Mergesort中选择了Mergesort,因为它提供了更好的保证。

不确定Microsoft为什么选择Quicksort,也许他们选择了Quicksort,尽管这样做会使它们在某些微基准上看起来更好一些?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.