Ich habe FILE_A mit über 300.000 Zeilen und FILE_B mit über 30 Millionen Zeilen. Ich habe ein Bash- Skript erstellt, das jede Zeile in FILE_A in FILE_B erfasst und das Ergebnis des grep in eine neue Datei schreibt.
Dieser gesamte Vorgang dauert über 5 Stunden.
Wie kann ich die Leistung meines Skripts verbessern?
Ich benutze grep -F -m 1
als grep Befehl. FILE_A sieht folgendermaßen aus:
123456789
123455321
und FILE_B ist wie folgt:
123456789,123456789,730025400149993,
123455321,123455321,730025400126097,
Mit Bash habe ich also eine while
Schleife, die die nächste Zeile in FILE_A auswählt und in FILE_B übergreift. Wenn das Muster in FILE_B gefunden wird, schreibe ich es in die Datei result.txt.
while read -r line; do
grep -F -m1 $line 30MFile
done < 300KFile
quelle
Hier ist eine Perl- Antwort für die Nachwelt. Ich mache dies routinemäßig, um 1M-Leitungen mit 30-35M-Leitungen abzugleichen. Der Vorgang dauert ca. 10 Sekunden.
Hash zuerst FILE_A:
Dann , wenn Ihre große Datei begrenzt ist , und weiß , was Spalte nach gehen, überprüfen Sie nur die Existenz der Raute - Taste , wie Sie unten FILE_B laufen, die viel, viel schneller als die Überprüfung auf Gleichheit oder reguläre Ausdrücke:
Wenn Ihre größere Zieldatei nicht gut analysiert werden kann, verliert dieses Skript seinen Wert, da ein Großteil seiner Geschwindigkeit darauf zurückzuführen ist, dass die Engine für reguläre Ausdrücke nicht gestartet werden muss.
quelle
Wenn Ihnen die Programmierung nichts ausmacht, sollten Sie Suffixbäume (oder eine Variante) verwenden.
Sie können
FILE_B
mit dem Ukkonen-Algorithmus in linearer Zeit vorverarbeiten . Anschließend fragen Sie jede ZeileFILE_A
zeitlich linear in der Zeilenlänge ab und erhalten alle übereinstimmenden Zeilennummern (möglicherweise muss der Baum ein wenig angepasst werden), die Sie in eine Ergebnisdatei schreiben können.Die gesamte Prozedur läuft in der Zeit O (n + Nm) ab, wenn n die Länge von
FILE_B
,N
die Anzahl der Zeilen inFILE_A
und m die Länge der längsten Zeile in istFILE_A
- dies ist im Wesentlichen eine lineare Laufzeit. Schlägt die quadratische Zeit, die Ihr ursprünglicher Ansatz benötigt, um Größenordnungen.quelle
Ich habe die
--mmap
Flagge kürzlich gefunden, hatte keine Gelegenheit, sie zu testen, aber ich freue mich über Ihre Ergebnisse. Hier ist die Beschreibung von der Manpage:Siehe dies oder das für weitere Informationen über
mmap
.quelle
--mmap
Dosis nichts entleert, würde ich einen Lauf mit--mmap
und einen ohne empfehlen . Und dann verwenden Sie, umwc
zu sehen, dass Sie die gleiche Menge an Ausgabe haben - dies sollte ein robuster Test sein, wenn man bedenkt, dass wir zweimal grep ausgeführt haben und nur ein Flag unterschiedlich war.Warum fügst du diese Datei nicht in eine Datenbank ein? Datenbanken sind wirklich gut darin, einen effizienten Merge-, Hash- oder Nested-Loop-Join wie diesen durchzuführen. Und sie sind wirklich gut darin, virtuellen Speicher zu nutzen
quelle