なぜJavaはプリミティブで基数ソートを使用しないのですか?


12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) 基数ソートではなく、「調整されたクイックソート」として実装されます。

少し前に速度を比較しましたが、n> 10000のようなものを使用すると、基数ソートは常に高速になりました。どうして?

回答:


17

私はそれを推測します:

  • Array.sortは、クイックソートとして実装されます。これは、クイックソートがコンパレータを使用して適切な時間に何でもソートできるためです。
  • 10000エントリのリストをソートすることはそれほど一般的ではありません。10000以上の要素のデータ構造にアクセスするのはかなり一般的です。順序を維持する必要がある場合、最小の要素が必要になるたびに配列全体を並べ替えるよりも、バランスの取れた検索ツリーを使用する方がよい場合があります。
  • 大学が何を教えるかもしれないが、プリミティブのソートはそれほど一般的ではありません。

重要なのは、標準ライブラリに最適化する必要があるというのは、それほど一般的なユースケースではないということです。パフォーマンスの問題があり、10000 + intの配列のソートが実際にボトルネックであるとプロファイリングで判断するアプリケーションを作成した場合、ソートを手動で記述するか、最初のデータ構造の選択を再検討することもできます場所。


100%確実ではありませんが、TimSortは現在いくつかのケースで使用されていると思います。
マルタインVerburg

1
しかし、Array.sortのようなものはなく、複数のArray.sortsがあり、これは数値型に特化したものに関する質問でした。
ダヌビアセーラー

6

Back2dosはそれをすべて言った、私は最も重要だと思うポイントをさらに明確にしようとします:

基数の並べ替えでは、配列内に含まれる実際のプリミティブ値のみを、そのバイナリ数字パターンに基づいて並べ替えることができます。実際の実際のソフトウェアエンジニアリングシナリオでは、このケースはほとんど発生しません。より頻繁に行う傾向があるのは、より複雑な(非プリミティブ)データ構造の配列の並べ替えです。また、インデックスの配列を他のエンティティに並べ替えることもあります。

現在、他のエンティティへのインデックスの配列は、実際にはプリミティブの配列ですが、ソート順は、インデックスではなくインデックスによってインデックス付けされたエンティティを比較するコンパレータインターフェイス(および/またはC#のデリゲート)によって提供されます。したがって、ソート順はプリミティブの値の順序とまったく関係がないため、このシナリオでは基数ソートはまったく役に立ちません。

例:

文字列の配列があります:[0] = "Mike"、[1] = "Albert"、[2] = "Zoro"。次に、これらの文字列にインデックスの配列を宣言します:[0] = 0、[1] = 1、[2] = 2。次に、インデックスの配列を並べ替え、インデックス自体ではなく、これらのインデックスによって参照される実際の文字列を比較するコンパレータに渡します。ソート後、インデックスの結果の配列は次のようになります。[0] = 1、[1] = 0、[2] = 2。ご覧のとおり、この並べ替え順序は、配列内に含まれる値のバイナリパターンとは関係ありませんが、このインデックスの配列を走査し、対応する各文字列を取得することで、並べ替えられた順序で文字列にアクセスします。

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