
Warum ist das WC-Dienstprogramm so langsam?
Wenn ich es auf einer großen Datei ausführe, dauert es etwa 20-mal länger als md5sum:
MyDesktop:/tmp$ dd if=/dev/zero bs=1024k count=1024 of=/tmp/bigfile
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.687094 s, 1.6 GB/s
MyDesktop:/tmp$ time wc /tmp/bigfile
0 0 1073741824 /tmp/bigfile
real 0m45.969s
user 0m45.424s
sys 0m0.424s
MyDesktop:/tmp$ time md5sum /tmp/bigfile
cd573cfaace07e7949bc0c46028904ff /tmp/bigfile
real 0m2.520s
user 0m2.196s
sys 0m0.316s
Es handelt sich nicht nur um einen merkwürdigen Randzustand, der dadurch entsteht, dass die Datei voller Nullen ist. Ich sehe den gleichen Unterschied in der Leistung, selbst wenn die Datei mit zufälligen Daten gefüllt ist oder eine Textdatei ist.
(dies ist auf Ubuntu 13.04, 64 Bit)
Antwort1
Ich habe mir also die Quelle angesehen und es sieht so aus, als ob die Verlangsamung bei der Verarbeitung von Doppelbyte-Zeichen liegt. Im Wesentlichen muss für jedes eingelesene Zeichen ein Aufruf durchgeführt werden, um zu mbrtowc()
versuchen, es in ein breites Zeichen umzuwandeln. Anschließend wird dieses breite Zeichen getestet, um festzustellen, ob es ein Worttrennzeichen, Zeilentrennzeichen usw. ist.
LANG
Wenn ich meine Gebietsschemavariable tatsächlich vom Standard ändere en_US.UTF-8
(UTF-8 ist ein Mehrbyte-Zeichensatz) und sie auf " C
" (einfacher Einzelbyte-Zeichensatz) setze, wc
kann ich Einzelbyte-Optimierungen verwenden, was den Vorgang erheblich beschleunigt und nur etwa ein Viertel der Zeit in Anspruch nimmt wie zuvor.
Außerdem muss es nur jedes Zeichen überprüfen, wenn es Wort- ( -w
), Zeilenlängen- ( -L
) oder Zeichenzählungen ( -m
) durchführt. Wenn es nur Byte- und/oder Zeilenzählungen durchführt, kann es die Verarbeitung breiter Zeichen überspringen und läuft dann extrem schnell – schneller als md5sum
.
Ich habe es durchlaufen lassen , und die Funktionen, die zum Verarbeiten der Multibyte-Zeichen ( , , , usw.) gprof
verwendet werden, nehmen alleine etwa 30 % der Ausführungszeit in Anspruch, und der Code, der den Puffer durchläuft, ist viel komplexer, weil er Schritte variabler Größe durch den Puffer für Zeichen variabler Größe verarbeiten muss, sowie alle teilweise vervollständigten Zeichen, die den Puffer umfassen, wieder an den Anfang des Puffers zurückstopfen muss, damit sie beim nächsten Mal verarbeitet werden können.mymbsinit()
mymbrtowc()
myiswprint()
Nachdem ich nun weiß, wonach ich suchen muss, habe ich einige Posts gefunden, in denen die Langsamkeit von UTF-8 bei einigen Dienstprogrammen erwähnt wird:
https://stackoverflow.com/questions/13913014/grepping-a-huge-file-80gb-any-way-to-speed-it-up http://dtrace.org/blogs/brendan/2011/12/08/2000x-performance-win/
Antwort2
Nur eine Vermutung, aber Sie vergleichen gewissermaßen Äpfel mit Birnen, was das, wc
was geschieht, und das, was md5sum
geschieht, betrifft.
md5sums Aufgabe
Bei md5sum
der Verarbeitung einer Datei wird die Datei einfach als Stream geöffnet und dann der Stream durch denMD5-Prüfsummenfunktiondas sehr wenig Speicher benötigt. Es ist im Wesentlichen an CPU und Festplatten-E/A gebunden.
WCs Aufgabe
Beim wc
Ausführen tut es viel mehr, als nur die Datei Zeichen für Zeichen zu analysieren. Es muss die Struktur der Datei tatsächlich Zeile für Zeile analysieren und feststellen, wo die Grenzen zwischen den Zeichen sind und ob es sich um eine Wortgrenze handelt oder nicht.
Beispiel
Denken Sie an die folgenden Zeichenfolgen und daran, wie sich jeder der Algorithmen beim Parsen durch sie bewegen müsste:
“Hello! Greg”
“Hello!Greg”
“Hello\nGreg”
“A.D.D.”
“Wow, how great!”
“wow \n\n\n great”
“it was a man-eating shark.”
Bei MD5 bewegt es sich trivial durch diese Zeichenfolgen, Zeichen für Zeichen. Denn wc
es muss entscheiden, was eine Wort- und Zeilengrenze ist, und die Anzahl der Vorkommen, die es sieht, im Auge behalten.
Weitere WC-Diskussionen
ich habe das gefundenProgrammier-Challenge von 2006in dem die Implementierung wc
in .NET erläutert wird. Die Schwierigkeiten sind ziemlich offensichtlich, wenn Sie sich den Pseudocode ansehen. Dies könnte also helfen, Licht in die Frage zu bringen, warum es wc
so viel langsamer zu sein scheint als andere Vorgänge.