Снова grep: LANG может замедлить обработку в более чем два раза.
Подкралось незаметно, проявившись на больших файлах.
Причём, и в файле (по которому идёт греп), и в запросе - символы только ASCII с кодами < 127.
grep у меня на Gentoo собран так:
Полез делать вызывать strace, обнаружил, что когда LANG=ru_RU.UTF-8, то открываются два дополнительных файлика (которые, судя по всему, ставяться из glibc):
Вот такие вилы с производительностью из-за интернационализации в grep'е на моей платформе. :-(
Upd: Возвращаясь к выводу "strace -r ...", всплывают следующие подробности.
Если вывести tail'ы отсортированных по timestamp'ам выводов strace'а, получается (строки с реальным содержимым файла намеренно вычищены):
Т.е. это grep что-то у себя там делает.
На команде "dd if=one_gig of=/dev/null bs=1048576 count=1024" эффект с подтормаживанием из-за локали - не проявляется.
Причём, и в файле (по которому идёт греп), и в запросе - символы только ASCII с кодами < 127.
user@host /tmp $ ls -la some.txt -rw-r--r-- 1 max max 23806702 Дек 18 22:18 some.txt user@host /tmp $ export LANG= user@host /tmp $ time grep -F sometext some.txt > /dev/null real 0m0.040s user 0m0.027s sys 0m0.013s user@host /tmp $ export LANG=ru_RU.UTF-8 user@host /tmp $ time grep -F sometext some.txt > /dev/null real 0m1.186s user 0m1.180s sys 0m0.003s user@host /tmp $Т.е., больше, чем в два раза grep притормаживает, если LANG=ru_RU.UTF-8 на тех же данных из основных символов ASCII. Ощутимо больше чем.
grep у меня на Gentoo собран так:
[ebuild R ] sys-apps/grep-2.5.4-r1 USE="nls pcre"Флаг pcre на результат не оказывает, проверял. Значит, nls.
Полез делать вызывать strace, обнаружил, что когда LANG=ru_RU.UTF-8, то открываются два дополнительных файлика (которые, судя по всему, ставяться из glibc):
open("/usr/lib64/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=12585536, ...}) = 0
mmap(NULL, 12585536, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f82ac0a2000
close(3) = 0
.........
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=26050, ...}) = 0
mmap(NULL, 26050, PROT_READ, MAP_SHARED, 4, 0) = 0x7f82ad449000
close(4) = 0Но при использовании опции "-r" ("Print a relative timestamp upon entry to each system call. This records the time difference between the beginning of successive system calls.") становится понятным, что нет какого-то конкретного места, задержка "размазана" между всеми вызовами.Вот такие вилы с производительностью из-за интернационализации в grep'е на моей платформе. :-(
Upd: Возвращаясь к выводу "strace -r ...", всплывают следующие подробности.
Если вывести tail'ы отсортированных по timestamp'ам выводов strace'а, получается (строки с реальным содержимым файла намеренно вычищены):
- Для LANG=:
0.000171 read(3, ..., 32768) = 32768 0.000172 read(3, ..., 32768) = 32768 0.000172 read(3, ..., 32768) = 32768 0.000172 read(3, ..., 32768) = 32768 0.000172 read(3, ..., 32768) = 32768 0.000173 read(3, ..., 32768) = 32768 0.000173 read(3, ..., 32768) = 32768 0.000174 read(3, ..., 32768) = 32768 0.000175 read(3, ..., 32768) = 32768 0.000175 read(3, ..., 32768) = 32768 0.000177 read(3, ..., 32768) = 32768 0.000178 read(3, ..., 32768) = 32768 0.000179 read(3, ..., 32768) = 32768 0.000180 read(3, ..., 32768) = 32768 0.000180 read(3, ..., 32768) = 32768 0.000182 read(3, ..., 32768) = 32768 0.000182 read(3, ..., 32768) = 32768 0.000184 read(3, ..., 32768) = 32768 0.000187 read(3, ..., 32768) = 32768 0.000216 read(3, ..., 32768) = 32768 0.000226 read(3, ..., 32768) = 32768 0.000234 read(3, ..., 32768) = 32768 0.000242 brk(0) = 0x1c4c000 0.000283 read(3, ..., 32768) = 32768 0.000337 read(3, ..., 32768) = 32768 0.000556 brk(0) = 0x1c4c000 0.000783 read(3, ..., 32768) = 32768 0.001535 read(3, ..., 32768) = 32768 0.001603 read(3, ..., 32768) = 32768 0.002046 read(3, ..., 32768) = 32768
- Для export LANG=ru_RU.UTF-8
0.001789 read(3, ..., 32768) = 32768 0.001790 read(3, ..., 32768) = 32768 0.001806 read(3, ..., 32768) = 32768 0.001814 read(3, ..., 32768) = 32768 0.001823 read(3, ..., 32768) = 32768 0.001823 read(3, ..., 32768) = 32768 0.001825 read(3, ..., 32768) = 32768 0.001826 read(3, ..., 32768) = 32768 0.001830 read(3, ..., 32768) = 32768 0.001833 read(3, ..., 32768) = 32768 0.001841 read(3, ..., 32768) = 32768 0.001922 read(3, ..., 32768) = 32768 0.002062 read(3, ..., 32768) = 32768 0.002168 read(3, ..., 32768) = 32768 0.002221 read(3, ..., 32768) = 32768 0.002419 read(3, ..., 32768) = 32768 0.002474 read(3, ..., 32768) = 32768 0.002498 read(3, ..., 32768) = 32768 0.002790 read(3, ..., 32768) = 32768 0.002817 read(3, ..., 32768) = 32768 0.003124 read(3, ..., 32768) = 32768 0.003256 read(3, ..., 32768) = 32768 0.003266 read(3, ..., 32768) = 32768 0.003305 fstat(1, {st_mode=S_IFREG|0644, st_size=3529, ...}) = 0 0.003466 read(3, ..., 32768) = 32768 0.003489 read(3, ..., 32768) = 32768 0.003592 read(3, ..., 32768) = 32768 0.003807 read(3, ..., 32768) = 32768 0.048357 write(1, ... 0.065736 read(3, ..., 32768) = 32768
Т.е. это grep что-то у себя там делает.
На команде "dd if=one_gig of=/dev/null bs=1048576 count=1024" эффект с подтормаживанием из-за локали - не проявляется.