大量のデータで機能するソートアルゴリズム


12

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

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

私はこれが良い解決策だと思います(複雑さO(nx log(n)))が、メインメモリに収まらない大きなデータセットで動作できる他の(おそらくより高速な)ソートアルゴリズムがあるかどうか知りたいです。

編集

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

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

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


1
どのようなデータですか?異なるデータセットは、目的に最適な異なるアルゴリズムを意味します。
-whatsisname

テキストファイルであり、行を並べ替える必要があります。行は固定長ではありませんが、長さはあまり変化しません(レコードごとに約50文字)。
ジョルジオ

3
私はあなたの環境や制約を知りませんが、可能な限りソートのためにデータベースを使用します。これは、ほぼ100%エラーがなく、私のコードよりもはるかに効率的であるためです。
-NoChance

私はLinux / Javaに取り組んでいます。マージソートを実装しましたが、非常にスムーズに動作するようです。数百万行のソートにはかなり時間がかかりますが、たまにこれを行うだけで済みます。
ジョルジオ

@Giorgio、このようなアルゴリズムを実装しているのは良いことです。実稼働環境では、データベースを使用することをお勧めします。速度だけでなく、信頼性とメンテナンスの容易さのためにも。
-NoChance

回答:


13

ソートと検索に関する標準的なリファレンスは、Knuth、Vol。3。そこから始めましょう。

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


2
参照していただきありがとうございます。Knuthの本で興味深い資料を見つけることはほぼ確実です。メモリ不足のソート手法が今日関連していないかどうかはわかりません。たぶん、日常的な一般的なタスクではないかもしれませんが、非常に大きなデータセットを処理する必要がある状況はまだたくさんあると想像できます。
ジョルジオ

Knuthのアルゴリズムは常に役立ちます。たとえば、ヒープソートバッファとソートのマージは非常に効果的であり、実装が非常に簡単です。
サルタン

4
参照資料は無料ではないため、あまり有用な答えではありません。OPについては、グーグルで答えを探すことをお勧めします。この種の情報がウェブを掘り下げて見つけることができる場合、本を入手するために50ドルを支払う必要はありません。もちろん、あなたはおそらく(から無料のためにこれをダウンロードすることができエヘン)特定のサイトにも。受け入れられた答えに値することはほとんどありません。
トーマスエディング

1
@ThomasEdingには、「ライブラリ」と呼ばれるものがあり、「書籍」と呼ばれるこれらの陳腐化した情報ストレージおよび検索デバイスが大量に含まれています。「図書館」は「本」を無料で貸し出しできるようにします。あなたの特定の「図書館」があなたが求める特定の「本」を持っていない場合、彼らは「図書館」が他の「図書館」から「本」を借りることができる「相互図書館貸し出し」と呼ばれる無料サービスも提供しますそれをあなたに貸してください。
ジョンR.ストローム

6

UNIX sortコマンドのような外部R-Wayマージは、適切な代替手段です。あなたの定式化から、それがあなたが「マージソート」で意図したアルゴリズムであるかどうかはわかりません。あなたがそれを知らないなら、見てください。


ありがとう。外部R-Wayマージは、私が考えていたものとは異なるようです。興味深い読書。
ジョルジオ

4

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

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

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

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

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

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

そう:

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

答えてくれてありがとう。「インプレースまたはマルチレコード」とはどういう意味ですか?
ジョルジオ

申し訳ありませんが、回答を校正してください。複数のファイルを意味します。インプレースは、ほとんどの場合、データベースが必要になる固定レコードサイズとインデックス付けを意味します。
ビルK

いいえ、適切ではありません。レコードは固定サイズではありません。現在の実装では4つの一時ファイルを使用しています。
ジョルジオ

出力をコードで解釈できますか、または特定の形式(フラットテキストファイル)である必要がありますか?何かが追加されるたびに、またはたまにしかソートする必要がある頻度はどれくらいですか?何かが追加されると、最後に追加されるだけですか、それを追加するコードを書くことができますか?
ビルK

各行は解析してレコードにできます(ファイルはCSVファイルです)が、ほとんどのフィールドはテキストです。時々(たとえば、毎月)ソートする必要があり、現在の実装でソートするには約1時間かかります。行を挿入するために、適切な場所に行を挿入するコードを書くことができます。これまでのコードでは、このようなツールを書くのに20分かかりました。
ジョルジオ

3

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


1
+1:興味深いリンク。マージソートはマップ/リデュースの例ではありません。マップはサブリストのソートに対応し、リデュースはマージに対応しますか?
ジョルジオ

そのように見えるかもしれませんが、Hadoopを使用して、自分で作成する代わりにこれを行うことができます。
m3th0dman

1

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

= O(n + d)n:要素の数、d =データに関する直感がある場合の最大数の長さ。「桁」の長さが最大数であることがわかっている場合。したがって、200万個の6桁の数字=> 0(n)がある場合は線形です。


0

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

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

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

0

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

1台のマシンで9時間で128GBのデータ(各項目100バイト)をソートし、ソートされたデータをほとんど時間なしでバイナリ検索できます。

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

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