Подтвердить что ты не робот

Является ли Perl или C более быстрым при разборе?

У меня есть несколько очень больших файлов журналов, и мне нужно их разобрать. Простота реализации, очевидно, указывает мне на Perl и regex combo (в которых я все еще новичок). Но как насчет скорости? Будет ли быстрее реализовать его в C? Каждый файл журнала имеет порядок 2 ГБ.

4b9b3361

Ответ 1

Я очень сомневаюсь, что C будет быстрее Perl, если вы не будете вручную компилировать RE.

С помощью ручной компиляции я имею в виду кодирование конечного автомата (FSM) напрямую, а не использование механизма RE для его компиляции. Этот подход означает, что вы можете оптимизировать его для своего конкретного случая, который часто может быть быстрее, чем полагаться на более универсальный движок.

Но это не то, что я когда-либо предлагал всем, кому не приходилось писать компиляторы или парсеры, прежде чем без пользы lex, yacc, bison или других подобных инструментов.

Обобщенные двигатели, такие как PCRE, обычно мощные и достаточно быстрые (для моих нужд все равно, и эти потребности часто были очень требовательными).

При использовании общего механизма RE он должен иметь возможность обрабатывать всевозможные случаи, независимо от того, написана ли она на C или Perl. Когда вы думаете о том, что быстрее, вам нужно сравнить только то, что двигатели RE написаны для обоих случаев (подсказка: механизм Perl RE не написан на Perl).

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

Вы можете найти различия в коде поддержки вокруг RE, но это будет минимальным, особенно если это простой цикл чтения/совпадения/вывода.

Ответ 2

  • Наивно написанный парсер, основанный на регулярном выражении на Perl, будет быстрее, чем наивно написанный парсер, основанный на регулярном выражении.
  • Хорошо написанный парсер, основанный на регулярном выражении на Perl, будет намного быстрее, чем наивно написанный синтаксический анализатор на основе регулярных выражений.
  • Хорошо написанный синтаксический анализатор на основе регулярных выражений C будет немного быстрее, чем хорошо написанный синтаксический анализатор на основе регулярных выражений на Perl. (Это также будет в два раза сложнее писать и в десять раз сложнее отлаживать.)

Ответ 3

Средство регулярного выражения Perl сильно оптимизировано. Здесь Perl сияет, вам не должно быть проблем с работой с файлом размером 2 ГБ в Perl, и производительность должна быть легко сопоставима с версией C. Кстати: пытались ли вы искать уже законченный парсер журнала? Их много.

Ответ 4

Если вы в равной степени владеете C и Perl, ответ прост:

  • Запишите его в Perl.
  • Если он слишком медленный, профилируйте его и исправьте.
  • Если он все еще слишком медленный, и проблема в чрезмерном использовании процессора или ОЗУ, подумайте о том, чтобы записать его на C.

Как правило, я бы сказал, что это применимо, если вы не являетесь своего рода C godlet, который может ловко манипулировать основами реальности посредством пуассантного манипулирования указателями и типами.

Серьезно, реализация регулярных выражений в perl очень быстро, гибко и хорошо протестирована. Любой написанный вами код может быть быстрым и гибким, но он никогда не будет так тщательно проверен.

Поскольку вы новичок в Perl и regex, важно помнить, что есть ресурсы, которые могут предоставить отличную помощь, если вам это нужно. Есть даже хорошие учебники в прекрасное руководство.

Что бы вы ни делали, не делайте этого:

for my $line ( <$log> ) {
    # parse line here.
}

Вы будете считывать весь файл журнала в память, и это займет много времени, так как ваша система меняет местами и свопами (и, возможно, сбой).

Вместо этого используйте цикл while:

while (defined( my $line = <$log> )) {
    # parse line here.
}

Ответ 5

Если вы действительно нуждаетесь для использования регулярных выражений, то движок регулярного выражения Perl трудно превзойти. Однако многие проблемы синтаксического анализа могут быть решены более эффективно без них - например, если вам просто нужно разделить строку на определенный символ, в этом случае C, вероятно, будет быстрее.

Если производительность имеет первостепенное значение, вы должны попробовать оба языка и измерить разницу в скорости. В противном случае просто используйте тот, с которым вам наиболее удобно.

Ответ 6

Я предполагаю (вместо бенчмаркинга фактических данных Alphaneo, которых у меня нет), что обработка ввода-вывода будет ограничивающим фактором здесь. И я ожидал бы, что реализация Perl на Perl с использованием usefaststdio будет соответствовать или бить базовую реализацию C, но будет заметно медленнее без использования faststdio. (usefaststdio был включен по умолчанию в perl 5.8 и ранее для большинства платформ и отключен по умолчанию в perl 5.10.)

Ответ 7

Является ли скорость действительно фактором здесь? Вы действительно заботитесь о том, выполняется ли синтаксический анализ через 5 или 10 минут?

Перейдите к языку или инструменту, который предлагает лучшие функции синтаксического анализа и наиболее знакомы с ними.

Ответ 8

В прошлом я нашел, что C будет быстрее, но не настолько, что выбор был предрешенным.

Задумывались ли вы об использовании общего инструмента Log Parser, например Log Parser:

Лог-парсер - мощный, универсальный инструмент, обеспечивающий универсальный запрос доступ к текстовым данным, таким как журнал файлы, файлы XML и CSV файлы, так как а также основные источники данных на Операционная система Windows®, такая как Журнал событий, реестр, файл системы и Active Directory®.

Этот сайт содержит несколько общих парсеров журнала.

Ответ 9

Perl, очевидно, имеет некоторые накладные расходы по сравнению с C. Но эти накладные расходы могут быть незначительными, если вы проводите большую часть времени внутри функций регулярного выражения Perl, реализованных в C.

Ответ 10

Отчасти это зависит от того, как синтаксический анализ будет интегрирован в приложение. Если приложение является парсером, то Perl будет хорошо, просто из-за этого он будет обрабатывать все, что его окружает, но если он интегрирован DIRECTLY в большее приложение, то вполне возможно, что вы можете захотеть взглянуть на нечто вроде Lex ( или Flex в эти дни): http://en.wikipedia.org/wiki/Lex_(software) Этот инструмент генерирует синтаксический анализатор для вас, и вы можете интегрировать код C/С++ непосредственно в ваше программное обеспечение.

Что касается соображений скорости, я согласен с большинством других респондентов здесь, что зрелость используемой библиотеки будет доминирующим фактором, а Perl ОЧЕНЬ зрелым. Я не знаю, насколько зрелы некоторые из других библиотек (например, регулярное выражение, доступное для С++ из Boost), но, поскольку большая часть вашего времени обработки будет в библиотеке, проблемы с языком, вероятно, являются вторичными.

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

Ответ 11

Да, вы можете сделать намного более быстрый парсер в C, если знаете, что делаете.

Однако для подавляющего большинства людей разумнее всего беспокоиться было бы простота реализации и поддержки кода. Быстрый парсер, с которым вы не можете работать правильно, никому не помогает.

Ответ 12

Если вы владеете Perl, используйте его. В противном случае используйте AWK и SED.

Разбор текста - это не то, что вы хотите сделать с C.

Ответ 13

Если вы разбираете журналы в общем формате журнала Apache, visitors, который написан на C, будет бить любой сопоставимый синтаксический анализатор perl-журнала по крайней мере в 2 раза.

Итак, найдите существующие синтаксические анализаторы и сравните их, если общий формат журнала.

Собственно написанный анализатор журналов в C всегда будет значительно быстрее, чем правильно написанный парсер журнала в Perl, основываясь на моих прошлых опытах.

Ответ 14

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

если (/[A-Za-Z] +/о)

Это приведет к тому, что выражение будет скомпилировано только один раз и для последующего повторного использования этого результата вместо каждой последующей итерации цикла.

Вооруженный этим усовершенствованием, я был бы очень удивлен, если бы ваш парсер Perl не прогуливался по всей реализации C, которую вы могли бы реализовать в реалистичном промежутке времени.

Ответ 15

Если вы хотите прочитать 2 Гб по perl, лучше использовать sysread (с большим размером блока enougth, например 256k или 512k). PerlIO использует слишком маленький размер блока - 4k, он неэффективен. См. PerlMonks для получения дополнительной информации о размере блока PerlIO.