Sortieren eines Datenstroms vor dem Schreiben in die Datei in nodejs

8

Ich habe eine Eingabedatei, die möglicherweise bis zu 1M Datensätze enthalten kann und jeder Datensatz würde so aussehen

field 1 field 2 field3 \n

Ich möchte diese Eingabedatei lesen und sie basierend auf field3 sortieren, bevor ich sie in eine andere Datei schreibe.

hier ist was ich bisher habe

%Vor%

Ich bin im Grunde an diesem Punkt fest, alles, was ich habe, ist die Fähigkeit, aus einer Datei zu lesen und in eine andere zu schreiben, gibt es eine Möglichkeit, diese Daten effizient zu sortieren, bevor Sie es schreiben

    
Community 22.01.2016, 22:17
quelle

4 Antworten

13

DB und sort-stream sind feine Lösungen, aber DB könnte ein Overkill sein und ich denke, sort-stream sortiert schließlich die gesamte Datei in ein In-Memory-Array (in through End Callback), also denke ich, dass die Leistung im Vergleich zur ursprünglichen Lösung ungefähr gleich ist.
(aber ich habe keine Benchmarks ausgeführt, also könnte ich mich irren).

Also, nur für den Hack, ich werde eine andere Lösung einwerfen:)

BEARBEITEN: Ich war gespannt, wie groß der Unterschied sein wird, also habe ich ein paar Benchmarks gemacht.

Die Ergebnisse waren sogar für mich überraschend, stellt sich heraus, sort -k3,3 Lösung ist bei weitem besser, x10 mal schneller als die ursprüngliche Lösung (eine einfache Array-Sortierung), während nedb und sort-stream solutions sind mindestens x18 mal langsamer als die ursprüngliche Lösung (dh mindestens x180 mal langsamer als sort -k3,3 ).

(Siehe Benchmark-Ergebnisse unten)

Wenn Sie sich auf einem * nix-Rechner (Unix, Linux, Mac, ...) befinden, können Sie ganz einfach sort -k 3,3 yourInputFile > op_rev.txt verwenden und das Betriebssystem für Sie sortieren lassen.
Sie werden wahrscheinlich eine bessere Leistung erzielen, da das Sortieren nativ erfolgt.

Oder wenn Sie die sortierte Ausgabe in Node verarbeiten möchten:

%Vor%

Hoffe das hilft:)

BEARBEITEN: Hinzufügen einiger Benchmark-Details.

Ich war neugierig zu sehen, wie groß der Unterschied sein wird, also habe ich ein paar Benchmarks gemacht.

Hier sind die Ergebnisse (läuft auf einem MacBook Pro):

  • sort1 verwendet einen einfachen Ansatz, bei dem die Datensätze in% co_de sortiert werden %.
    Durchschn. Zeit: 35.6s (Baseline)

  • sort2 verwendet in-memory array , wie von Joe Krill vorgeschlagen. < br> Durchschn. Zeit: 11.1m (ungefähr x18.7 mal langsamer )
    (Ich frage mich warum. Ich habe nicht nachgegeben.)

  • sort3 verwendet sort-stream , wie von Tamas Hegedus vorgeschlagen. < br> Zeit: ungefähr 16m (ungefähr x27 mal langsamer )

  • sort4 sortiert nur, indem nedb in einem Terminal
    Durchschn. Zeit: 1,2 s (etwa 30 mal schneller
    )

  • sort5 verwendet sort -k 3,3 input.txt > out4.txt und verarbeitet die an stdout gesendete Antwort
    Durchschn. Zeit: 3,65s (ungefähr x9,7 mal schneller )

Yoav Aharoni 01.04.2016, 00:34
quelle
5

Sie können Streams für so etwas nutzen. Es gibt ein paar NPM-Module, die hilfreich sein werden - zuerst schließen Sie sie ein, indem Sie

ausführen %Vor%

über die Befehlszeile.

Dann:

%Vor%     
Joe Krill 30.03.2016 17:36
quelle
2

Sie haben zwei Möglichkeiten, abhängig davon, wie viele Daten verarbeitet werden. (1M Datensatzanzahl mit 3 Spalten sagt nicht viel über die Menge der tatsächlichen Daten aus)

Laden Sie die Daten in den Speicher, sortieren Sie sie an Ort und Stelle

%Vor%

Laden Sie die Daten in eine persistente Datenbank, lesen Sie geordnet

Verwenden Sie eine Datenbank-Engine Ihrer Wahl (zum Beispiel nedb , eine reine Javascript-Datenbank für nodejs)

BEARBEITEN : Es scheint, dass NeDB die gesamte Datenbank im Speicher hält, die Datei ist nur eine persistente Kopie der Daten. Wir müssen nach einer anderen Implementierung suchen. TingoDB sieht vielversprechend aus.

%Vor%     
Tamas Hegedus 26.03.2016 00:47
quelle
2

Ich hatte ziemlich ähnliches Problem, musste eine externe Sortierung durchführen.

Ich habe herausgefunden, nachdem ich einige Zeit damit verschwendet habe, dass ich die Daten in einer Datenbank laden und dann die gewünschten Daten daraus abfragen könnte.

Es ist nicht einmal wichtig, ob die Inserts nicht geordnet sind, solange mein Abfrageergebnis sein könnte.

Ich hoffe, es kann auch für Sie funktionieren.

Um Ihre Daten in eine Datenbank einzufügen, gibt es auf dem Knoten viele Werkzeuge, um eine solche Aufgabe auszuführen. Ich habe dieses Lieblingsprojekt , das einen ähnlichen Job macht.

Ich bin mir auch sicher, dass Sie Suche das Thema, finden Sie viel mehr Informationen.

Viel Glück.

    
Sombriks 26.03.2016 00:46
quelle