Warum ist das Dienstprogramm wc so langsam?
Wenn ich es auf einer großen Datei laufen lasse, dauert es ungefähr 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 ist nicht nur eine seltsame Randbedingung, da die Datei mit Nullen gefüllt ist. Ich sehe den gleichen Leistungsunterschied, auch wenn die Datei mit zufälligen Daten gefüllt ist oder eine Textdatei ist.
(Dies ist auf Ubuntu 13.04, 64 Bit)
performance
wc
Johnny
quelle
quelle
Antworten:
Also ging ich zur Quelle und es sieht so aus, als ob die Langsamkeit im Umgang mit Doppelbyte-Zeichen liegt. Grundsätzlich muss für jedes eingelesene Zeichen ein Aufruf erfolgen
mbrtowc()
, um zu versuchen, es in ein breites Zeichen umzuwandeln. Dieses breite Zeichen wird dann geprüft, um festzustellen, ob es sich um ein Worttrennzeichen, ein Zeilentrennzeichen usw. handelt.Tatsächlich kann ich, wenn ich meine Gebietsschemavariable
LANG
von der Standardvariable ändereen_US.UTF-8
(UTF-8 ist ein Multibyte-Zeichensatz) und auf "C
" (einfacher Einzelbyte-Zeichensatz) setze,wc
Einzelbyte-Optimierungen verwenden, was dies erheblich beschleunigt. dauert nur etwa ein Viertel so lange wie zuvor.Außerdem muss nur jedes Zeichen überprüft werden, ob es Wörter (
-w
), Zeilenlängen (-L
) oder Zeichen (-m
) zählt. Wenn es nur Byte- und / oder Zeilenzählungen durchführt, kann es die Verarbeitung breiter Zeichen überspringen und läuft dann extrem schnell - schneller alsmd5sum
.Ich lief es durch
gprof
, und die Funktionen, die die Multibyte - Zeichen (werden verwendet , um handhabenmymbsinit()
,mymbrtowc()
,myiswprint()
usw.) nehmen bis zu 30% der Ausführungszeit allein, und der Code , dass die Schritte durch den Puffer ist viel komplexer , weil es zu Behandeln Sie Schritte mit variabler Größe durch den Puffer für Zeichen mit variabler Größe und füllen Sie alle unvollständigen Zeichen, die sich über den Puffer erstrecken, wieder an den Anfang des Puffers, damit sie beim nächsten Mal verarbeitet werden können.Nachdem ich nun weiß, wonach ich suchen muss, habe ich einige Posts gefunden, in denen die Langsamkeit von utf-8 mit einigen Dienstprogrammen erwähnt wird:
/programming/13913014/grepping-a-huge-file-80gb-any-way-to-speed-it-up http://dtrace.org/blogs/brendan/2011/12/08 / 2000x-performance-win /
quelle
md5sum
Erlaubt Ihnen niemals das Zählen der Wortnummer undwc
berechnet nicht den MD5-Hash der Datei! Es ist, als würde man fragen, warum mein Auto im Vergleich zu meiner Schreibmaschine beim Schreiben von Text so langsam ist.wc
bei der Verarbeitung von Mehrbyte-Zeichen die CPU tatsächlich gebunden ist.Nur eine Vermutung, aber Sie vergleichen Äpfel mit Orangen in Bezug auf das, was sie
wc
tun, und das, was siemd5sum
tun.md5sums aufgabe
Beim
md5sum
Verarbeiten einer Datei wird die Datei einfach als Stream geöffnet und der Stream über die MD5-Prüfsummenfunktion ausgeführt, die nur sehr wenig Speicher benötigt. Es ist im Wesentlichen CPU & Disk I / O gebunden.wc's aufgabe
Wenn
wc
es ausgeführt wird, ist es viel mehr, als nur die Datei zeichenweise zu analysieren. Es muss die Struktur der Datei analysieren und Zeilen für Zeilen bestimmen, wo sich die Grenzen zwischen den Zeichen befinden und ob es sich um eine Wortgrenze handelt oder nicht.Beispiel
Stellen Sie sich die folgenden Zeichenfolgen vor und wie sich jeder Algorithmus durch sie bewegen müsste, wenn sie sie analysieren:
In MD5 werden diese Zeichenfolgen nur zeichenweise durchlaufen. Denn
wc
es muss entscheiden, was eine Wort- und Liniengrenze ist, und die Anzahl der Vorkommen verfolgen, die es sieht.Zusätzliche WC-Diskussionen
Ich habe diese Codierungsherausforderung aus dem Jahr 2006 gefunden , in der die Implementierung
wc
in .NET erläutert wird . Die Schwierigkeiten liegen auf der Hand, wenn Sie sich einen Teil des Pseudocodes ansehen. Dies könnte also hilfreich sein, um zu verstehen, warum dieserwc
Vorgang so viel langsamer ist als andere Vorgänge.quelle
wc
zählt mehrere Dinge, wie es die Datei analysiert. Beim Parsen der Datei werden die Anzahl der Wörter, Zeilen und Bytes gezählt. Lesen Sie die Manpage!wc
das Zählen von Zeilen das interne Parsen einschränkt, sodass nur diese Dinge gezählt werden oder nur die Zeilenergebnisse gemeldet werden , obwohl immer noch alles gezählt wird.