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 ändere en_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 als md5sum
.
Ich lief es durch gprof
, und die Funktionen, die die Multibyte - Zeichen (werden verwendet , um handhaben mymbsinit()
, 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 /