Denn eine wirklich große Datei wie 1 GB wc -l
ist langsam. Haben wir eine schnellere Möglichkeit, die Anzahl der Zeilenumbrüche für eine bestimmte Datei zu berechnen?
command-line
wc
Prosti
quelle
quelle
0x0A
Unversehrtheit überprüft werden muss, ist E / A zweifellos der Engpass.wc
haben, zu viel Overhead zu haben, können Sie versuchen, Ihren eigenen zu implementierenforeach byte in file: if byte == '\n': linecount++
. Wenn es in C oder Assembler implementiert ist, wird es meiner Meinung nach nicht schneller, außer vielleicht im Kernelbereich eines RTOS mit höchster Priorität (oder verwenden Sie dafür sogar einen Interrupt - Sie können einfach nichts anderes mit dem System tun. .. in Ordnung, ich schweife ab ;-))time wc -l some_movie.avi
eine nicht zwischengespeicherte Datei schnell bearbeitet, was dazu führte5172672 some_movie.avi -- real 0m57.768s -- user 0m0.255s -- sys 0m0.863s
. Was @thrig im Grunde als richtig erweist, erschüttert I / O in diesem Fall Ihre Leistung.time wc -l some_large_file_smaller_than_cache
zweimal hintereinander durchzuführen und zu sehen, wie schnell der zweite Vorgang ist,time wc -l some_large_file_larger_than_cache
und dann zu sehen, wie sich die Zeit zwischen den Läufen nicht ändert. Bei einer Datei mit ~ 280 MB beträgt die Zeit zwischen 1,7 Sekunden und 0,2 Sekunden, bei einer Datei mit 2 GB jedoch beide Male 14 Sekunden./usr/bin/time wc -l <file>
sagt das aus? Was ist Ihre Hardware? Ist es schneller, wenn Sie den Befehl wiederholt ausführen? Wir brauchen wirklich mehr Informationen;)Antworten:
Sie können versuchen , in C zu schreiben:
Speichern Sie zB,
wcl.c
kompilieren Sie zB mitgcc wcl.c -O2 -o wcl
und führen Sie mit ausDadurch werden in etwa 370 ms (wiederholte Durchläufe) Zeilenumbrüche in einer 1-GB-Datei auf meinem System angezeigt . (Durch Erhöhen der Puffergröße wird die zu erwartende Zeit geringfügig verlängert - BUFSIZ sollte nahezu optimal sein.) Dies ist sehr vergleichbar mit den ~ 380 ms , von denen ich komme
wc -l
.Mmaping gibt mir eine bessere Zeit von ungefähr 280 ms , aber es hat natürlich die Einschränkung, auf echte Dateien beschränkt zu sein (kein FIFOS, keine Terminaleingabe usw.):
Ich habe meine Testdatei erstellt mit:
und fügte einige Test-Zeilenumbrüche hinzu mit:
und ein Hex-Editor.
quelle
for
Schleife) kann von Vorteil sein, sodass einige Fortschritte erzielt werden können, während ein Thread auf die Eingabe wartet. Auf der anderen Seite kann dies die E / A-Planung behindern. Ich kann es also nur empfehlen, es auszuprobieren und zu messen!read()
Version kann von Vorauslesen profitieren.Sie können die von @pskocik vorgeschlagene Lösung verbessern, indem Sie die Anzahl der Anrufe auf reduzieren
read
. Es gibt viele Aufrufe zum Lesen vonBUFSIZ
Chunks aus einer 1-GB-Datei. Der übliche Ansatz hierfür ist das Erhöhen der Puffergröße:BUFSIZ
erhöhen . Auf meinem Debian 7 ist es 8192. Mit dem ursprünglichen Programm sind das 120.000 Lesevorgänge. Sie können sich wahrscheinlich einen 1-MB-Eingabepuffer leisten, um diesen um den Faktor 100 zu reduzieren.Beachten Sie beim Benchmarking der verschiedenen Ansätze möglicherweise, dass einige Systeme (z. B. Linux) den größten Teil des nicht verwendeten Speichers Ihres Computers als Festplatten-Cache verwenden. Vor einiger Zeit (vor fast 20 Jahren, erwähnt in den abscheulichen FAQ ) war ich verwirrt über unerwartet gute Ergebnisse eines (nicht sehr guten) Paging-Algorithmus, den ich entwickelt hatte, um mit Bedingungen mit wenig Speicher in einem Texteditor umzugehen. Mir wurde erklärt, dass es schnell lief, weil das Programm aus den Speicherpuffern arbeitete, die zum Lesen der Datei verwendet wurden, und dass es nur dann einen Geschwindigkeitsunterschied geben würde, wenn die Datei erneut gelesen oder geschrieben würde.
Gleiches gilt für
mmap
(in einem anderen Fall, der noch auf meiner To-Do-Liste steht, um ihn in eine FAQ aufzunehmen, meldete ein Entwickler sehr gute Ergebnisse in einem Szenario, in dem der Festplatten-Cache der eigentliche Grund für Verbesserungen war). Die Entwicklung von Benchmarks erfordert Zeit und Sorgfalt, um die Gründe für die gute (oder schlechte) Leistung zu analysieren.Weiterführende Literatur:
quelle
dd
MB-Puffern langsamer als 8 KB. Der Standardwert von 8 KB für wc ist eigentlich ziemlich gut gewählt und für eine Vielzahl von Systemen nahezu optimal.