Ich suche nach Sortieralgorithmen, die mit einer großen Datenmenge arbeiten können, dh die auch dann funktionieren, wenn nicht der gesamte Datensatz gleichzeitig im Hauptspeicher gespeichert werden kann.
Der einzige Kandidat, den ich bisher gefunden habe, ist die Sortierung nach Zusammenführung: Sie können den Algorithmus so implementieren, dass er Ihren Datensatz bei jeder Zusammenführung durchsucht, ohne alle Daten gleichzeitig im Hauptspeicher zu speichern. Die Variation der Zusammenführungssorte, die ich im Auge habe, wird in diesem Artikel im Abschnitt Verwenden mit Bandlaufwerken beschrieben .
Ich halte dies für eine gute Lösung (mit der Komplexität O (nx log (n))), bin aber gespannt, ob es andere (möglicherweise schnellere) Sortieralgorithmen gibt, die für große Datenmengen geeignet sind, die nicht in den Hauptspeicher passen.
BEARBEITEN
Hier sind einige weitere Details, wie in den Antworten gefordert:
- Die Daten müssen regelmäßig sortiert werden, z. B. einmal im Monat. Ich muss nicht einige Datensätze einfügen und die Daten inkrementell sortieren lassen.
- Meine Beispieltextdatei hat ungefähr 1 GB UTF-8-Text, aber ich wollte das Problem generell lösen, auch wenn die Datei beispielsweise 20 GB groß wäre.
- Es befindet sich nicht in einer Datenbank und kann aufgrund anderer Einschränkungen nicht vorhanden sein.
- Die Daten werden von anderen als Textdatei gespeichert, ich habe meinen eigenen Code, um diese Textdatei zu lesen.
- Das Format der Daten ist eine Textdatei: Neue Zeilenzeichen sind Satztrennzeichen.
Eine mögliche Verbesserung bestand darin, die Datei in Dateien aufzuteilen, die klein genug sind, um im Speicher sortiert zu werden, und schließlich alle diese Dateien mit dem oben beschriebenen Algorithmus zusammenzuführen.
quelle
Antworten:
Der kanonische Verweis auf Sortieren und Suchen ist Knuth, Vol. 3 . Fang dort an.
Das Buch wurde ursprünglich geschrieben, als Computer viel kleiner und langsamer waren als heute, was Sortiertechniken außerhalb des Arbeitsspeichers wichtiger machte, als sie heute wahrgenommen werden.
quelle
Externe R-Way-Zusammenführung wie im UNIX-
sort
Befehl ist eine gute Alternative. Nach Ihrer Formulierung bin ich mir nicht sicher, ob dies der Algorithmus ist, den Sie mit "Sortieren zusammenführen" gemeint haben, und wenn Sie ihn nicht kennen, schauen Sie ihn sich an.quelle
Ohne weitere Details ist "Sortierung zusammenführen" wahrscheinlich die beste Antwort, die Sie erhalten, Sie können jedoch je nach Ihren Anforderungen etwas viel schlaueres implementieren.
Können Sie zum Beispiel einfach einen speicherinternen Index der Datei erstellen und dann alle Werte auf einmal kopieren, um die Position der verschiedenen Schlüsselwerte zwischenzuspeichern? Passt 1/2 auf einmal in den Speicher oder 1/1000000? Wenn es der zweite ist, können Sie möglicherweise keinen Index in den Speicher einpassen. Wenn Sie beim ersten die beiden Hälften effizienter sortieren und dann in einem einzigen letzten Schritt zusammenführen.
Zum Teufel, da Sie nicht angegeben haben, ist es möglich, dass sich Ihre Daten alle in einer Datenbank befinden. Wenn ja, können Sie einfach eine Indextabelle erstellen und als gut bezeichnen (ich nehme an, dass dies nicht der Fall ist, aber darauf hinweisen Ihre Situation ist entscheidend für die Lösung eines so komplizierten Problems.
Wenn du es nur einmal machen willst und nach einem sehr schnellen Hack suchst, klingt es so, als wäre diese externe Merge-Sortierung ein guter Anfang, wenn du Unix verwendest (da es anscheinend eingebaut ist).
Wenn Sie die Reihenfolge beibehalten müssen und immer einen einzelnen Datensatz hinzufügen, ist eine Einfügesortierung erforderlich (das Hinzufügen eines einzelnen Datensatzes zu sortierten Daten ist immer eine Einfügesortierung).
Können Sie den Code steuern, der die Daten "liest"? Wenn ja, dann helfen viele Formen der Indizierung (anstatt durch Verschieben von Daten auf der Festplatte zu sortieren) VIEL (wird tatsächlich eine absolute Voraussetzung sein).
So:
quelle
Wenn Sie wirklich eine skalierbare Lösung wünschen, sollten Sie sich TeraSort ansehen, die Standard-Sortierimplementierung mit Kartenreduzierung. Weitere Details zu StackOverflow .
quelle
Möglicherweise interessieren Sie sich für eine Eimersorte . Die durchschnittliche Fallleistung ist die lineare Zeit.
= O (n + d) n: Anzahl der Elemente und d = Länge der größten Anzahl, wenn Sie eine Ahnung von Ihren Daten haben, d. H. Wenn Sie wissen, wie viele "Ziffern" lang sind, ist Ihre größte Zahl. Wenn Sie also 2 Millionen 6-stellige Zahlen => 0 (n) haben, ist dies linear.
quelle
Verwenden Sie einen externen Sortieralgorithmus für Zusammenführungen (wenn Ihre Daten kontinuierlich sind) oder eine Bucket-Sortierung mit Zählsortierung als Implementierung der Sortierung für Buckets (wenn Ihre Daten diskret und gleichmäßig verteilt sind).
Der wahrscheinlich beste Ansatz ist es, eine eigene Index- / Zuordnungsdatei zu erstellen, wenn das Inkrement klein ist.
quelle
Ich habe gerade einige abstrakte Strukturen namens "Big Queue" und "Big Array" erstellt, um das Sortieren und Suchen von Big Data auf einer einzelnen Maschine mit begrenztem Speicher zu vereinfachen. Grundsätzlich ähnelt der verwendete Algorithmus dem oben erwähnten - externe Zusammenführungssortierung.
Ich kann 128 GB Daten (jedes Element 100 Byte) in 9 Stunden auf einer einzelnen Maschine sortieren und dann die sortierten Daten fast ohne Zeitaufwand binär durchsuchen.
Hier ist ein Beitrag zum Durchsuchen von Big Data mithilfe meiner Open Source Big Queue und Big Array-Strukturen.
quelle