Встроенный grep медленнее, чем grep, который поставляется с Linux

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

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

  Версия: grep (GNU grep) 2.5.1
  Размер: 88896 байт
  вывод ldd: 
 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:

  Версия: 2.5.1
  Размер: 256437 байт
  вывод ldd:
 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 (22430 мсек) при выполнении поиска по регулярному выражению в большом текстовом файле списка.

Ниже приведена команда, которую я использовал для определения времени..

% time src / grep ". * asa. *" large_list.txt> / dev / null
реальный 0m22.430s
пользователь 0m22.291s
sys 0m0.080s

ИЛИ ЖЕ

% time bin/grep ".*asa.*" large_list.txt > /dev/null
реальный 0m0,331s
пользователь 0m0.236s
sys 0m0.081s

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

Может ли какой-нибудь орган помочь мне с какими опциями может быть собран системный 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

Вывод./configure:

проверка BSD-совместимой установки... /usr/bin/install -c проверка правильности среды сборки... да проверка многопоточного mkdir -p... /bin/mkdir -p проверка gawk.... gawk проверяет, устанавливает ли make наборы $(MAKE)... да, проверяет тип системы сборки... x86_64-unknown-linux-gnu проверяет тип системы хоста... x86_64-unknown-linux-gnu проверяет gawk... (cached) gawk проверяет gcc... gcc проверяет имя выходного файла по умолчанию для компилятора C... a.out проверяет, работает ли компилятор C... да проверяет, выполняется ли кросс-компиляция... не проверяется суффикс исполняемых файлов.... проверять суффикс объектных файлов... проверять, используем ли мы компилятор GNU C... да проверять, принимает ли gcc -g... да проверять опцию gcc для принятия ISO C89... проверять не нужно стиль include, используемый make... GNU для проверки зависимостей стиль gcc... gcc3 для проверки BSD-совместимой установки... /usr/bin/install -c проверка для ranlib... ranlib проверка для getconf... getconf checki ng для значения CFLAGS для запроса поддержки больших файлов... проверка значения LDFLAGS для запроса поддержки больших файлов... проверка значения LIBS для запроса поддержки больших файлов... проверка для _FILE_OFFSET_BITS... нет проверки для _LARGEFILE_SOURCE... нет проверка на _LARGE_FILES... нет проверки на прототипы функций... да проверка, как запустить препроцессор C... gcc -E проверка на grep, который обрабатывает длинные строки, и -e... /bin/grep проверка на egrep... /bin/grep -E проверка на наличие заголовочных файлов ANSI C... да проверка на sys/types.h... да проверка на sys/stat.h... да проверка на stdlib.h... да проверка на string.h... да проверка на memory.h... да проверка на strings.h... да проверка на inttypes.h... да проверка на stdint.h... да проверка на unistd.h.. да, проверка для string.h... (кэширование) да, проверка для size_t... да, проверка для ssize_t... да, проверка на соответствие const ANSI C... да, проверка для inttypes.h... да, проверка для неподписанных длинных длинных... да проверка на ANSI C файлы заголовков... (кэшированные) да проверка на string.h... (кэширование) да проверка на stdlib.h... (кэширование) да проверка удобства использования sys/param.h... да проверка sys/param.h наличие... да проверка на sys/param.h... да проверка на memory.h... (кэшировано) да проверка на unistd.h... (кэшировано) да проверка юзабилити libintl.h... да проверка наличие libintl.h... да проверка на libintl.h... да проверка удобства использования wctype.h... да проверка присутствия wctype.h... да проверка на наличие wctype.h... да проверка удобства использования wchar.h.... да, проверяет наличие wchar.h... да, проверяет наличие wchar.h... да, проверяет наличие файла dirent.h, определяющего DIR... да, проверяет наличие библиотеки, содержащей opendir... ничего не требуется, проверяя, используются ли макросы в режиме stat file-mode не работают... нет проверки для работы alloca.h... да проверка для alloca... да проверка, возвращает ли closedir пустоту... нет проверки для stdlib.h... (кэшировано) да проверка для unistd.h... (кэшировано) да проверка на getpagesize... да проверка на работающий mmap... да проверка для btowc... да проверка на isascii... да проверка на iswctype... да проверка на mbrlen... да проверка на memmove... да проверка на setmode... нет проверка на strerror... да проверка на wcrtomb... да проверка на wcscoll... да проверка на wctype... да проверка правильности объявления mbrtowc и mbstate_t... да проверка на stdlib.h... (кэшировано) да проверка на mbstate_t... да проверка на memchr... да проверка на stpcpy... да проверка на strtoul... да проверка на atexit... да проверка на fnmatch... да проверка на stdlib.h... (кэшировано) да проверка, определяет ли strtoumax как макрос... нет проверки на strtoumax... да проверяется, объявлен ли strtoul... да проверяется, объявлен ли strtoull... да проверяется strerror в -lcposix... нет проверяется на inline... inline проверка на off_t... да проверка, используем ли мы GNU C Library 2.1 или новее... да проверка удобства использования argz.h... да проверка присутствия argz.h... да проверка argz.h... да проверяет возможность использования limit.h... да проверяет наличие limit.h... да проверяет наличие limit.h... да проверяет удобство использования locale.h... да проверяет присутствие locale.h... да проверяет locale.h... да проверка юзабилити nl_types.h... да проверка наличия nl_types.h... да проверка nl_types.h... да проверка юзабилити malloc.h... да проверка присутствия malloc.h... да проверка на malloc.h... да проверка юзабилити stddef.h... да проверка наличия stddef.h... да проверка на stddef.h... да проверка на stdlib.h... (кэшируется) да проверка для string.h... (кэшируется) да проверка для unistd.h... (кэшируется) да проверка для sys/param.h... (кэшируется) да проверка для feof_unlocked... да проверка для fgets_unlocked.. да, проверка для getcwd... да, проверка для getegid... да, проверка для geteuid... да, проверка для getgid... да, проверка для getuid... да, проверка для mempcpy... да, проверка для munmap... да, проверка на putenv... да, проверка на setenv... да, проверка на setlocale... y проверяет stpcpy... (кэшируется) да проверяется strchr... да проверяется strcasecmp... да проверяется strdup... да проверяется strtoul... (кэшируется) да проверяется tsearch... да проверяется для __argz_count... да проверка на __argz_stringify... да проверка на __argz_next... да проверка на iconv... да проверка на объявление iconv... 
         extern size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); проверка для nl_langinfo и CODESET... да проверка для LC_MESSAGES... да проверка, запрашивается ли NLS... да проверка запрашиваемого включенного gettext... нет проверки для libintl.h... (кэшировано) да проверка для GNU gettext в libc... да проверка на dcgettext... да проверка на msgfmt... /usr/bin/msgfmt проверка на gmsgfmt... /usr/bin/msgfmt проверка на xgettext... /usr/bin/xgettext проверка на бизона... проверка версии бизона на бизона... 2.3, хорошо, проверка каталогов, которые нужно установить... аааааааааааааааааааааааааааааАааааааааааааааааа таяя еще раз! lt nb nl pl pt pt_BR ro ru rw sk sl sr sv tr uk vi zh_TW проверка на соответствие файла dos... нет проверки типа хост-системы... (кэшировано) x86_64-unknown-linux-gnu проверка типа хост-системы... (кэшировано) x86_64-unknown-linux-gnu проверка на наличие среды DJGPP... нет проверки на разделитель переменных среды...: проверка на работоспособность re_compile_pattern... да проверка на наличие getopt_long... да настройка: ПРЕДУПРЕЖДЕНИЕ: включена библиотека lib/regex.c не используется для проверки, объявлен ли strerror_r... да, для проверки strerror_r... да, для проверки, возвращает ли strerror_r символ *... нет проверки для strerror... (кэшировано) да, для проверки strerror_r... (кэшировано) да проверка на наличие vprintf... да проверка на доступность... нет проверки на наличие заголовочных файлов ANSI C... (кэшировано) да проверка на работоспособность malloc... да проверка на работоспособность realloc... да проверка на pcre_exec в -lpcre... yes
configure: создание./config.status
config.status: создание Makefile
config.status: создание lib/Makefile
config.status: создание lib/posix/Makefile
config.status: создание src/Makefile
config.status: создание тестов / Makefile
config.status: создание po/Makefile.in
config.status: создание intl/Makefile
config.status: ПРЕДУПРЕЖДЕНИЕ:  intl/Makefile.in, похоже, игнорирует параметр --datarootdir config.status: создание doc/Makefile
config.status: создание m4/Makefile
config.status: создание vms/Makefile
config.status: создание начальной загрузки / Makefile
config.status: создание конфигурации.h
config.status: config.h не изменяется config.status: выполнение команд depfiles config.status: выполнение команд default-1 config.status: создание po/POTFILES
config.status: создание po/Makefile
config.status: выполнение stamp-h команды

Спасибо, кумар

5 ответов

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

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

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

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

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

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

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

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

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

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

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

Еще одна мысль, которую стоит отметить, кроме опций -O, похоже, что вы строите с отладочными символами "-g".

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

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

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

Другие вопросы по тегам