web-dev-qa-db-ja.com

大量のデータを処理するソートアルゴリズム

大量のデータを処理できる、つまりデータセット全体をメインメモリに一度に保持できない場合でも機能する並べ替えアルゴリズムを探しています。

これまでに見つけた唯一の候補はマージソートです。すべてのデータをメインメモリに一度に保持せずに、各マージでデータセットをスキャンするようにアルゴリズムを実装できます。私が念頭に置いているマージソートのバリエーションは、セクションこの記事 で説明されています。テープドライブでの使用

これは良い解決策だと思います(複雑度O(n x log(n)を使用)。しかし、メインメモリに収まらない大規模なデータセットで機能する他の(おそらくより高速な)ソートアルゴリズムがあるかどうか知りたいです。

[〜#〜]編集[〜#〜]

回答に必要な詳細を以下に示します。

  • データは定期的にソートする必要があります。月に一度。いくつかのレコードを挿入して、データを段階的にソートする必要はありません。
  • 私のサンプルテキストファイルは約1 GBのUTF-8テキストですが、ファイルがたとえば20 GBであっても、一般的に問題を解決したいと考えました。
  • それはデータベースにはなく、他の制約のため、それはできません。
  • データはテキストファイルとして他のユーザーによってダンプされます。このテキストファイルを読み取るための独自のコードがあります。
  • データの形式はテキストファイルです。改行文字はレコードの区切り文字です。

私が考えていた改善の1つは、ファイルをメモリ内でソートするのに十分小さいファイルに分割し、最後に上記のアルゴリズムを使用してこれらすべてのファイルをマージすることでした。

12
Giorgio

ソートと検索に関する正規のリファレンスは Knuth、Vol。 です。そこから始めましょう。

この本は元々、コンピュータが現在よりもはるかに小さくて遅いときに書き直されたため、現在のメモリよりもメモリ不足のソート手法が重要になっています。

13
John R. Strohm

外部Rウェイマージ UNIXの場合と同様に、sortコマンドを使用することをお勧めします。あなたの定式化から、それが「マージソート」で意図したアルゴリズムであるかどうかはわかりません。それがわからない場合は、見てください。

6
thiton

詳細な説明がなければ、「マージソート」がおそらく最良の答えになりますが、要件に応じて、よりスマートなものを実装できます。

たとえば、単にファイルのメモリ内インデックスを作成し、すべての値を一度にコピーして、さまざまなキー値の場所をキャッシュできますか? 1/2は一度にメモリに収まりますか、それとも1/1000000ですか?それが2番目の場合は、インデックスをメモリに収めることができない場合があり、最初の場合は両方の半分をより効率的に並べ替え、最後の1つの手順でそれらをマージできます。

地獄、それを指定しなかったので、データがすべてデータベースにある可能性があります。そうであれば、インデックステーブルを作成してそれを適切に呼び出すことができます(これは当てはまらないと思いますが、このような複雑な問題を解決するには、状況が重要です)。

あなたが一度だけそれをやりたいと思っていて、非常に迅速なハックを探しているなら、あなたがunixを実行しているならば、外部マージソートが良いスタートになるように思えます(それは明らかに組み込まれているので)

順序を保つ必要があり、常に単一のレコードを追加する場合は、挿入ソートが必要になります(ソートされたデータに単一のレコードを追加することは常に挿入ソートです)。

データを「読み取る」コードを制御できますか?その場合、(ディスク上でデータを移動して並べ替えるのではなく)インデックス付けの多くの形式が、LOTに役立ちます(実際には絶対要件です)。

そう:

  • インプレースまたは複数のファイル?
  • 一度だけ、定期的に、または常に並べ替えておく?
  • メモリよりどのくらい大きいですか(データセット全体を通過するためのメモリロードの数)?
  • データベースにありますか?できますか?
  • データを読み取るコードを制御していますか、それとも他の人がファイルを直接ダンプしていますか?
  • ファイル形式? (テキスト?固定レコード?)
  • 私が尋ねなかった他の特別な状況はありますか?
4
Bill K

スケーラブルなソリューションが本当に必要な場合は、map-reduceを使用した標準のソート実装であるTeraSortを検討する必要があります。 StackOverflowの詳細

3
m3th0dman

バケットソート に興味があるかもしれません。平均的なケースのパフォーマンスは線形時間です。

= O(n + d)n:要素の数、d =データについて直感がある場合の最大数の長さ、つまりあなたはあなたの最大の数字が何桁あるか知っているなら。したがって、200万の6桁の数値がある場合=> 0(n)したがって線形です。

1
stonemetal

外部マージソートアルゴリズム(データが連続している場合)、または バケットソートカウントソート をバケットのソートの実装として使用(データが離散的で均一に分散している場合) )。

おそらく、最善の方法は、増分が小さい場合に独自のインデックス/マッピングファイルを作成することです。

  1. どういうわけか「データベース」を注文
  2. すべてのエントリに整数を割り当てます(1、2、3、4、...、n)(より良い方法:疎なインデックスを使用します)
  3. 増分を追加するときは、左の数値が小さく、右の数値が大きいか等しいギャップを見つけるだけです(バイナリ検索の一部の変更バージョンでは難しくないはずです)。
  4. 挿入、ギャップは十分に大きいが、そうでない場合:インデックスを再作成する(再ソートしない):-)
0
malejpavouk

ビッグキューとビッグアレイと呼ばれる抽象的な構造を構築して、メモリが限られた単一のマシンでビッグデータのソートと検索タスクを簡素化しました。基本的に、使用されるアルゴリズムは、前述のアルゴリズム(外部マージソート)に似ています。

1台のマシンで128GBのデータ(各アイテム100バイト)を9時間で並べ替えることができ、並べ替えたデータをほとんど時間なくバイナリ検索できます。

ここ は、私のオープンソースの大きなキューと大きな配列構造を使用してビッグデータを検索する方法についての投稿です。

0
Bulldog