mpd

Снова grep: LANG может замедлить обработку в более чем два раза.

Dec 19, 2010 00:29

Подкралось незаметно, проявившись на больших файлах.
Причём, и в файле (по которому идёт греп), и в запросе - символы только 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'а, получается (строки с реальным содержимым файла намеренно вычищены):
  1. Для 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
  2. Для 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
Надо помнить, что "-r - the time difference between the beginning of successive system calls". Вывод time'а говорит, что основное вермя разницы - в user time, а не в system time.
Т.е. это grep что-то у себя там делает.
На команде "dd if=one_gig of=/dev/null bs=1048576 count=1024" эффект с подтормаживанием из-за локали - не проявляется.

gentoo, freesoftware, linux, posix

Previous post Next post
Up