Javaおよび.NET:異なるソートアルゴリズムがデフォルトで使用される理由


19

デフォルトで異なるソートアルゴリズムJava.NET Framework使用する理由と疑問に思います。

Java Array.Sort()では、デフォルトでMerge Sortアルゴリズムを使用し、Wikipedia.comが次のように述べています。

Javaでは、Arrays.sort()メソッドは、データ型に応じてマージソートまたは調整されたクイックソートを使用し、実装効率のために7つ未満の配列要素がソートされている場合は挿入ソートに切り替えます

.NET Framework Array.Sort/List.Sort()では、クイックソートをデフォルトのソートアルゴリズムとして使用します(MSDN):

List.Sort()は、QuickSortアルゴリズムを使用するArray.Sortを使用します。この実装は、不安定なソートを実行します。つまり、2つの要素が等しい場合、それらの順序は保持されない可能性があります。対照的に、安定したソートでは、等しい要素の順序が保持されます。

優れた「アルゴリズムの比較」表を見ると、両方のアルゴリズムの動作がワーストケースとメモリ使用量の観点からかなり異なっていることがわかります。

ここに画像の説明を入力してください

どちらJava.NETエンタープライズ・ソリューション開発のための素晴らしいフレームワークです、両方が組込み開発のためのプラットフォームを持っています。では、なぜ彼らはデフォルトで異なるソートアルゴリズムを使用しているのでしょうか?


1
これら2種類の比較の詳細については、stackoverflow.com
q / 680541/866022

回答:


10

コンピューター自体が決定的であるように、コンピューター工学は厳密な科学ではありません。同じ問題ドメインを与えられた2人が分析を実行し、問題のすべての制約を満たす2つの異なるソリューションを開発します。これらのどれが一般的な場合に「より良い」かを経験的に決定することは困難または不可能かもしれません。

私の推測では、.NET QuickSortはMFCまたはWindows APIの何かの上に階層化されており、おそらくMergeSortのマルチスレッド化の利点がコンピューターにとっても考慮されていなかったWindowsのはるかに古いバージョンから継承されています当日。(編集: MS-DOS以来のソートの実装のこの選択によって証明されるように、Microsoft開発者は長い間QuickSortのファンでしたが、そうではありません)。

Javaは完全にプラットフォームに依存しないようにゼロから設計されたため、プラットフォーム固有の実装を使用することはできませんが、Javaは別の方法で進みました。MergeSortがトップに出た理由を誰が知っていますか。私の野生の推測は、実装が開発者が考え出した他の種類と比較して何らかのパフォーマンス競争に勝った、またはO(n)スペースのMergeSortがベストケースとワーストケースのパフォーマンスの観点から紙の上で最高に見えたということです(MergeSortにはQuickSortのような要素の選択に関連するアキレス腱がなく、そのベストケースはほぼ並べ替えられたリストですが、それは多くの場合QuickSortの最悪です)。マルチスレッドの利点が最初に考慮されたとは思いませんが、現在の実装はマルチスレッドである可能性があります。


1
List<T>.Sort.NETでは、CLRに実装されたネイティブメソッドを使用します(カスタム比較子を使用しない場合)が、OSライブラリに依存しません。
ジョーイ14年

1
@Keith-.NETは何の上にも階層化されておらず、プラットフォームに依存しないように設計されています。あなたは右ここ実装を見ることができます:github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/...
ロバート・マックリーン

@RobertMacLean-「.NETは何の上にも階層化されていません」というのは本当のステートメントではありませんが、問題のSort関数は完全に「マネージ」コードであることを示しました。暗号化サポート、WindowsデスクトップGUIライブラリ、Windows API相互運用(プロセスおよびスレッド制御を含む)を含む.NETの大部分は、MFCを含む既存のアンマネージコードにすべて基づいています。彼らはただある必要があります。Windows自体には、そのコードベースの非常にマイナーな.NETコンポーネントのみがあり、残りは管理されてい
ません-KeithS

QuickSortはMS-DOS以来選択されているアルゴリズムであるため、Microsoft開発者は他の実装よりもQuickSortの実証済みであり、このアルゴリズムで.NETのソートを実装する決定に影響を与えていたためです。
キース

この答えはとても間違っているので、正直ショックを受けました。
user9993

17

2つの異なる企業の異なる開発チームは、フレームワークとコンポーネントの通常のユースケースに関して異なる結論に達し、それに応じて実装することを決定しました。

基本的に、各企業は分析を行い、顧客ベースを見て、それに応じて異なる決定を下しました。

同じ結論に至るために異なる仮定と生データを使用して、異なる企業やチームによる分析を期待することはできません。


5
または、同じ仮定と生データ。。。
ワイアットバーネット

うん、それはおそらく習慣の力にして-マイクロソフトが(不安定な)クイックソートを使用して使用した、Javaは安定の一種で行きたかった...と、マージソートは最速知られて安定していた...
rogerdpack

12

Javaは現在Timsortを使用しているため、この質問は少し時代遅れです。(Java 7の時点)を

言及された特定のアルゴリズムのうち:

  • Quicksortは、O(n ^ 2)での最悪の場合のパフォーマンスが好ましくありませんが、少し軽量であり、メモリ消費量が少ないため、一般的なケースでパフォーマンスが向上します。

  • MergesortはO(n log n)で最悪の場合のパフォーマンスを保証していますが、オーバーヘッドとメモリ要件が少し増えています。また、自動的に安定しています(つまり、同じ要素を同じ順序で維持します)。

Javaデザイナーは、一般的にもう少し保守的で、「正しいこと」に集中しているように見えるので、より良い保証を提供するため、2つからMergesortを選んだのは驚くことではありません。

MicrosoftがQuicksortを選んだ理由は定かではありませんが、いくつかのマイクロベンチマークで見栄えが良くなるのでしょうか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.