Der schnellste Weg, um Duplikate in einer großen Wortliste zu löschen?

14

Ich muss eine große Wortliste deduplizieren. Ich habe mehrere Befehle ausprobiert und hier und hier Nachforschungen angestellt , in denen erklärt wurde, dass der schnellste Weg zum Deduplizieren einer Wortliste awk zu verwenden scheint.

awk -> O (n)? sortieren -> O (n log n)?

Ich fand jedoch, dass dies nicht wahr zu sein scheint. Hier sind meine Testergebnisse:

sort -u input.txt -o output.txt 

echte 0m12.446s
Benutzer 0m11.347s
sys 0m0.906s

awk '!x[$0]++' input.txt > output.txt

echte 0m47.221s
Benutzer 0m45.419s
sys 0m1.260s

Die Verwendung von sort -u ist also 3,7-mal schneller. Warum ist das? Gibt es eine noch schnellere Methode zur Deduplizierung?

*********** Update ********

Wie jemand in den Kommentaren hervorhob, könnte es sein, dass meine Wortliste bereits zu einem gewissen Grad sortiert war. Um diese Möglichkeit auszuschließen, habe ich mit diesem Python-Skript zwei Wortlisten erstellt .

Liste1 = 7 MB
Liste2 = 690 MB

Ergebnisse AWK:
List1
real 0m1.643s
Benutzer 0m1.565s
sys 0m0.062s

List2
real 2m6.918s
Benutzer 2m4.499s
sys 0m1.345s

Ergebnisse SORT:
List1
real 0m0.724s
user 0m0.666s
sys 0m0.048s

List2
real 1m27.254s
user 1m25.013s
sys 0m1.251s

karlpy
quelle
Könnte es sein, dass Ihre Eingabedaten bereits sortiert sind?
Iruvar
Ich werde eine zufällige Liste mit Zahlen generieren und überprüfen, ob
karlpy
2
Bei der Big O-Notation geht es darum, was passiert, wenn die Eingabelänge gegen unendlich geht: Sie gibt an, dass ein Algorithmus mit großen Eingaben skaliert. Einige Algorithmen funktionieren bei kleinen Eingabegrößen besser.
Strg-Alt-Delor
1
Karlpy, in welcher Reihenfolge haben Sie ausgeführt? Das kann aufgrund des Datei-Cachings einen Unterschied machen
iruvar
1
@karlpy: "Ich habe den Dateinamen geändert ..." Wenn Sie meinen, dass Sie die Datei umbenannt haben, ist das nicht gut genug. Beim Umbenennen einer Datei wird dem alten Inode nur ein neuer Name zugeordnet, der weiterhin auf dieselben alten Datenblöcke verweist. Wenn sie zwischengespeichert wurden, sind sie immer noch zwischengespeichert. ISTM, dass eine viel bessere Technik darin besteht, (1) eine Kopie der Datei zu erstellen und dann (2) einen Befehl für eine Datei und (3) den anderen Befehl für die andere Datei auszuführen.
Scott

Antworten:

3

Sie stellen die falsche Frage oder stellen die Frage falsch und im falschen Stapel. Dies ist eine bessere Frage, die Sie im Programmier- / Stapelüberlauf stellen müssen, damit die Leute Ihnen Antworten geben können, die auf den Algorithmen basieren, die in awk und sort verwendet werden.

PS: Mach das auch mit nawk, mawk und gawk, um uns ein paar Details zu "zone into" zu geben;) und führe die Läufe wie jeweils 100 Mal mit den Werten für min, max, avg und Standardabweichung aus.

Auf jeden Fall geht es bei der vorliegenden Frage von CompSci 210 um die verwendeten Algorithmen. Beim Sortieren werden abhängig von der Größe und den Speicherbeschränkungen mehrere verwendet, um Dateien auf der Festplatte in temporären Dateien zu speichern und zusammenzuführen, sobald der Speicher voll ist. Sie müssen sich den Quellcode ansehen, um zu sehen, was passiert Der Befehl "specific sort (1)" wird auf dem Betriebssystem verwendet, auf dem Sie ihn ausführen. Erfahrungsgemäß wird er jedoch so oft wie möglich in den Speicher geladen. Führen Sie eine schnelle Sortierung durch, schreiben Sie auf die Festplatte, wiederholen Sie den Vorgang und wiederholen Sie den Vorgang end führt eine Zusammenführung der kleinen sortierten Dateien durch. Hier haben Sie also das O (n * log2 (N)) für die Teile und dann eine ungefähre O (n * log (n)) - Zusammenführungsoperation

awk: Der Mechanismus x [$ 0] ++ setzt voraus, dass Hashing verwendet wird. ABER das Problem beim Hashing, eine vermeintliche O (1) "Lookup" -Operation, sind Kollisionen und die Behandlung von Kollisionen. Dies kann zu Problemen führen, wenn die Daten nicht gut verteilt sind oder die Eimer usw. nicht voll sind. In großen Listen kann das Hashing zu einem großen Speicherproblem werden, wenn die Behandlung der Kollisionen nicht ordnungsgemäß erfolgt (und dies möglicherweise erforderlich ist) Stimmen Sie die Hashing-Algorithmen für die erwarteten Daten ab. Anschließend müssen Sie die Leistung der tatsächlichen Hashing-Funktionen überprüfen, und dann könnte das O (1) näher an einem O (log (n)) für die Einfügungen liegen (d. h. O (1) für die erste Suche, und wenn es NICHT existiert, fügen Sie es hinzu, das könnte sein O (log (n))), und das dann wird das n * O (1) ein * O (log (n)) = > O (n * log (n)), ganz zu schweigen davon, dass Sie die Dinge auch "interpretiert" machen :)

Hvisage
quelle
-2

Der Geschwindigkeitsunterschied besteht darin, dass 'sort' ein Befehl ( Link ) ist, während 'awk' eine Programmiersprache ( Link ) ist.

Der Befehl 'sort' übernimmt die Eingabe und gibt die Ausgabe zurück. Während 'awk' eine Programmiersprache ist, interpretiert sie zuerst den Code (Terminal-Befehl) und beginnt dann mit der Verarbeitung. So einfach ist das.

Zuhayer
quelle