созданный grep медленнее, чем grep, который идет с Linux

Я пытаюсь понять, почему grep, созданный мной, намного медленнее, чем тот, который идет с системой и пытающийся найти, какие параметры компилятора используются grep, который идет с системой.

Версия ОС: выпуск 5.3 CentOS (Финал) grep в системе:

  Version: grep (GNU grep) 2.5.1
  Size: 88896 bytes
  ldd output: 
 libpcre.so.0 => /lib64/libpcre.so.0 (0x0000003991800000)
 libc.so.6 => /lib64/libc.so.6 (0x0000003985a00000)
 /lib64/ld-linux-x86-64.so.2 (0x0000003984a00000)

grep создается мной:

  Version: 2.5.1
  Size: 256437 bytes
  ldd output:
 libpcre.so.0 => /lib64/libpcre.so.0 (0x0000003991800000)
 libc.so.6 => /lib64/libc.so.6 (0x0000003985a00000)
 /lib64/ld-linux-x86-64.so.2 (0x0000003984a00000)

Производительность системы grep (330 национальной безопасности) является путем быстрее, чем grep, который я создал (22 430 национальной безопасности) при запущении regex поиск на большом текстовом файле списка.

Следующее является командой, которую я привык для времени..

% time src/grep ".*asa.*" large_list.txt > /dev/null
real 0m22.430s
user 0m22.291s
sys 0m0.080s

ИЛИ

% time bin/grep ".*asa.*" large_list.txt > /dev/null
real 0m0.331s
user 0m0.236s
sys 0m0.081s

Система grep ясно использует некоторые optiomizing опции, который дает огромное различие в производительности.

Некоторое тело может помочь мне с тем, с какими опциями система grep может быть создана?

Вот опции компиляции для одного из исходных файлов, когда я создаю..
gcc -DLIBDIR=\"/usr/local/lib\" -DHAVE_CONFIG_H -I. -I.. -I.. -I. -I../intl -g -O2 -MT xstrtol.o -MD -MP -MF .deps/xstrtol.Tpo -c -o xstrtol.o xstrtol.c

Вывод./настраивать:

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gawk... (cached) gawk
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for a BSD-compatible install... /usr/bin/install -c
checking for ranlib... ranlib
checking for getconf... getconf
checking for CFLAGS value to request large file support... 
checking for LDFLAGS value to request large file support... 
checking for LIBS value to request large file support... 
checking for _FILE_OFFSET_BITS... no
checking for _LARGEFILE_SOURCE... no
checking for _LARGE_FILES... no
checking for function prototypes... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for string.h... (cached) yes
checking for size_t... yes
checking for ssize_t... yes
checking for an ANSI C-conforming const... yes
checking for inttypes.h... yes
checking for unsigned long long... yes
checking for ANSI C header files... (cached) yes
checking for string.h... (cached) yes
checking for stdlib.h... (cached) yes
checking sys/param.h usability... yes
checking sys/param.h presence... yes
checking for sys/param.h... yes
checking for memory.h... (cached) yes
checking for unistd.h... (cached) yes
checking libintl.h usability... yes
checking libintl.h presence... yes
checking for libintl.h... yes
checking wctype.h usability... yes
checking wctype.h presence... yes
checking for wctype.h... yes
checking wchar.h usability... yes
checking wchar.h presence... yes
checking for wchar.h... yes
checking for dirent.h that defines DIR... yes
checking for library containing opendir... none required
checking whether stat file-mode macros are broken... no
checking for working alloca.h... yes
checking for alloca... yes
checking whether closedir returns void... no
checking for stdlib.h... (cached) yes
checking for unistd.h... (cached) yes
checking for getpagesize... yes
checking for working mmap... yes
checking for btowc... yes
checking for isascii... yes
checking for iswctype... yes
checking for mbrlen... yes
checking for memmove... yes
checking for setmode... no
checking for strerror... yes
checking for wcrtomb... yes
checking for wcscoll... yes
checking for wctype... yes
checking whether mbrtowc and mbstate_t are properly declared... yes
checking for stdlib.h... (cached) yes
checking for mbstate_t... yes
checking for memchr... yes
checking for stpcpy... yes
checking for strtoul... yes
checking for atexit... yes
checking for fnmatch... yes
checking for stdlib.h... (cached) yes
checking whether  defines strtoumax as a macro... no
checking for strtoumax... yes
checking whether strtoul is declared... yes
checking whether strtoull is declared... yes
checking for strerror in -lcposix... no
checking for inline... inline
checking for off_t... yes
checking whether we are using the GNU C Library 2.1 or newer... yes
checking argz.h usability... yes
checking argz.h presence... yes
checking for argz.h... yes
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking locale.h usability... yes
checking locale.h presence... yes
checking for locale.h... yes
checking nl_types.h usability... yes
checking nl_types.h presence... yes
checking for nl_types.h... yes
checking malloc.h usability... yes
checking malloc.h presence... yes
checking for malloc.h... yes
checking stddef.h usability... yes
checking stddef.h presence... yes
checking for stddef.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking for unistd.h... (cached) yes
checking for sys/param.h... (cached) yes
checking for feof_unlocked... yes
checking for fgets_unlocked... yes
checking for getcwd... yes
checking for getegid... yes
checking for geteuid... yes
checking for getgid... yes
checking for getuid... yes
checking for mempcpy... yes
checking for munmap... yes
checking for putenv... yes
checking for setenv... yes
checking for setlocale... yes
checking for stpcpy... (cached) yes
checking for strchr... yes
checking for strcasecmp... yes
checking for strdup... yes
checking for strtoul... (cached) yes
checking for tsearch... yes
checking for __argz_count... yes
checking for __argz_stringify... yes
checking for __argz_next... yes
checking for iconv... yes
checking for iconv declaration... 
         extern size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
checking for nl_langinfo and CODESET... yes
checking for LC_MESSAGES... yes
checking whether NLS is requested... yes
checking whether included gettext is requested... no
checking for libintl.h... (cached) yes
checking for GNU gettext in libc... yes
checking for dcgettext... yes
checking for msgfmt... /usr/bin/msgfmt
checking for gmsgfmt... /usr/bin/msgfmt
checking for xgettext... /usr/bin/xgettext
checking for bison... bison
checking version of bison... 2.3, ok
checking for catalogs to be installed...  af be bg ca cs da de el eo es et eu fi fr ga gl he hr hu id it ja ko ky lt nb nl pl pt pt_BR ro ru rw sk sl sr sv tr uk vi zh_TW
checking for dos file convention... no
checking host system type... (cached) x86_64-unknown-linux-gnu
checking host system type... (cached) x86_64-unknown-linux-gnu
checking for DJGPP environment... no
checking for environ variable separator... :
checking for working re_compile_pattern... yes
checking for getopt_long... yes
configure: WARNING: Included lib/regex.c not used
checking whether strerror_r is declared... yes
checking for strerror_r... yes
checking whether strerror_r returns char *... no
checking for strerror... (cached) yes
checking for strerror_r... (cached) yes
checking for vprintf... yes
checking for doprnt... no
checking for ANSI C header files... (cached) yes
checking for working malloc... yes
checking for working realloc... yes
checking for pcre_exec in -lpcre... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating lib/Makefile
config.status: creating lib/posix/Makefile
config.status: creating src/Makefile
config.status: creating tests/Makefile
config.status: creating po/Makefile.in
config.status: creating intl/Makefile
config.status: WARNING:  intl/Makefile.in seems to ignore the --datarootdir setting
config.status: creating doc/Makefile
config.status: creating m4/Makefile
config.status: creating vms/Makefile
config.status: creating bootstrap/Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands
config.status: executing default-1 commands
config.status: creating po/POTFILES
config.status: creating po/Makefile
config.status: executing stamp-h commands

Спасибо, kumar

7
задан Michael Myers 23 December 2009 в 22:28
поделиться

5 ответов

Почему бы вам просто не получить SRPM CentOS для двоичного файла grep и не сравнить их параметры компиляции с вашими? Я предполагаю, что это намного эффективнее, чем когда все сообщество StackOverflow слепо копается в темноте, пока не наткнется на что-нибудь.

РЕДАКТИРОВАТЬ: Вы используете локаль с многобайтовой кодировкой? (Примечание: если вы не понимаете, что это означает, то ответ, вероятно, будет «Да», поскольку UTF-8 был стандартом по умолчанию для большинства дистрибутивов Linux в течение нескольких лет, и действительно RedHat (и, следовательно, CentOS) были самыми первыми, кто

В этом случае GNU grep будет медленным. И это относится не только к GNU grep, но и почти ко всем инструментам GNU, которые выполняют какую-либо обработку текста. FSF отказывается принимать какие-либо исправления для улучшения многобайтовой производительности, если не будет доказано, что эти патчи не замедляют кодирование фиксированной ширины. Однако, поскольку любой патч для повышения производительности для многобайтовых кодировок должен по крайней мере содержать где-то некоторую инструкцию if , фактически невозможно написать патч, который не работает на как минимум замедлить кодирование с фиксированной шириной, по крайней мере, на накладные расходы этого оператора if . Таким образом, производительность UTF-8 инструментов GNU будет и дальше отстой до скончания веков.

В любом случае, большинство дистрибьюторов Linux не наплевать на то, что думает FSF и все равно пропатчить GNU grep. Fedora Rawhide SRPM содержит патч под названием grep-2.5.3-egf-speedup.patch , который на несколько порядков увеличивает производительность GNU grep в UTF-8. (Поскольку этот патч уже выпущен в 2005 году, я предполагаю, что он также используется в CentOS.) Этот патч также используется в Mac OSX, Debian, Ubuntu, ..., почти никто не использует GNU grep, распространяемую GNU. Обработка текста в многобайтовой кодировке никогда не будет такой быстрой, как в кодировке с фиксированной шириной, но она должна быть, по крайней мере, сопоставима, а не в 50 раз (или даже в 1500 раз, как сообщают некоторые люди).

Есть еще один патч под названием dfa-optional , что заставляет grep просто использовать механизм регулярных выражений GNU libc вместо своего собственного, что не только намного быстрее при работе с UTF-8, но и имеет гораздо меньше ошибок.

] Итак, вы можете повторно запустить тесты с установленным параметром export LC_ALL = POSIX . Если это решит вашу проблему, вам необходимо применить один из двух вышеупомянутых исправлений.

Дополнительная информация также доступна в этих двух отчетах об ошибках RedHat:

Мораль истории: несмотря на распространенное мнение, Дистрибьюторы Linux действительно знают, что делают, по крайней мере, иногда. Не сомневайтесь в них.

10
ответ дан 6 December 2019 в 12:51
поделиться

Еще одно соображение, на которое следует обратить внимание, помимо параметров -O, это похоже на то, что вы строите с отладочными символами «-g».

Отладка обычно увеличивает двоичный размер и может снизить производительность указанного двоичного файла, Я бы сказал, что grep довольно стабилен, и для него не нужны символы отладки.

1
ответ дан 6 December 2019 в 12:51
поделиться

Вы скомпилировали с флагом -O2 . Почему вы не использовали флаг -03 . См. здесь для объяснения опций оптимизации, доступных в gcc.

Использование компилятора Intel ICC также может помочь повысить производительность, хотя это действительно зависит от приложения. Кроме того, это не бесплатно.

Редактировать, я только что видел флаг -g в вашей строке компиляции. Удалите это, поскольку он включает отладку, и это может привести к довольно серьезному снижению производительности

4
ответ дан 6 December 2019 в 12:51
поделиться

Какую версию GCC вы используете? IIRC, GCC 4 был значительно переработан, что на некоторое время сделало недействительным часть кода оптимизации.

1
ответ дан 6 December 2019 в 12:51
поделиться

При таком большом разрыве в производительности это, вероятно, разница в алгоритме / коде, а не только в уровне оптимизации компилятора. Что заставляет вас подозревать компилятор?

0
ответ дан 6 December 2019 в 12:51
поделиться