Являются ли preg_match() и preg_replace() медленными?

Я некоторое время программировал PHP, и я продолжаю читать, что вы должны использовать только preg_match и preg_replace, когда это необходимо, поскольку это замедляет производительность. Почему это? Было бы неплохо использовать 20 preg_matches в одном файле вместо использования другой функции PHP.

Ответ 1

Как сказал Майк Брант в своем ответе: "Нет ничего плохого в использовании каких-либо функций preg_*, если они вам понадобятся.
Вы хотите знать, неплохо ли иметь что-то вроде 20 preg_match вызовов в одном файле, ну, честно: я бы сказал, что слишком много. Я часто утверждал, что "если ваше решение проблемы зависит от более чем 3 регулярных выражений в любой момент времени, вы являетесь частью проблемы". Однако я иногда грешил против своей собственной мантры.

Если вы используете 20 preg_match звонков, скорее всего, вы можете вдвое сократить это число, просто взглянув на реальные регулярные выражения. Regex's, особенно регулярное выражение Perl, невероятно мощное, и стоит потратить время, чтобы узнать их. Причина, по которой они, как правило, медленнее, - это просто потому, что регулярное выражение должно анализироваться и "переводиться" на значительное количество ветвей и петель на некотором низком уровне. Если, скажем, вы хотите заменить весь нижний регистр a на верхний регистр char, вы можете использовать регулярное выражение, конечно, но в PHP это будет выглядеть так:

preg_replace('/a/','A',$string);

Посмотрите на выражение, первый аргумент: это строка, которая передается как аргумент. Эта строка будет проанализирована (при синтаксическом анализе, флаги будут проверены, будет создана строка соответствия, а затем строка будет итерирована, каждый char будет сопоставлен с шаблоном (в данном случае a), и если подстрока совпадает, он заменен.
Кажется, что это немного, но особенно учитывая, что последний шаг (сравнение подстрок и замены матчей) - это все, чего мы действительно хотим.

$string = str_replace('a','A',$string);

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

Короче: регулярное выражение медленнее, потому что выражение анализируется, проверяется и, наконец, преобразуется в набор простых инструкций низкого уровня.

Обратите внимание, что в некоторых случаях люди используют explode и implode для строковых манипуляций. Это также создает массив, который не может быть свободным. Учитывая, что вы сразу же взорвали тот же самый массив. Возможно, еще один вариант более желателен (и в некоторых случаях preg_replace может быть быстрее здесь).
В основном: регулярное выражение нуждается в дополнительной обработке, что простые строковые функции не требуют. Но когда есть сомнения, существует только один способ быть абсолютно уверенным: настройте тест script...

Ответ 2

Это действительно зависит от вашего варианта использования. Нет ничего по своей сути "плохо" в использовании регулярного выражения. Иногда это единственное доступное решение конкретной проблемы. Тем не менее, бывают случаи, когда простые функции манипуляции строками будут работать нормально. Они, как правило, быстрее, чем функции preg*, поэтому, если вы столкнулись с ситуациями, когда у вас есть script, который выполняется очень часто и/или имеет большое количество строковых манипуляций, которые могут быть выполнены, влияние использования регулярного выражения может начали ощущаться.

Как и в любом случае, вы должны протестировать в своем приложении и среде и решить, что лучше всего подходит вам.

Ответ 3

Не беспокойтесь о оптимизации, если у вас нет проблемы.

Не смотрите на области оптимизации без измерения с помощью чего-то вроде XDebug (http://xdebug.org).

Если ваш код занимает 100 мс для запуска с preg_match() и 110ms через какой-либо другой метод, вы действительно заботитесь о различии?

Сначала напишите для правильности и ясности, затем рассмотрите скорость.

Ответ 4

Проверьте, сколько времени потребуется (время отображения НАЧАЛО и ENDED):

var_dump( microtime(true) );

//...............  your function executions here.............

var_dump( microtime(true) );

Ответ 5

В зависимости от того, что вы делаете. Для сложных регулярных выражений просто используйте функции preg_, если вам нужны простые подстановки или аналогичные, идите с другими, более конкретными функциями, такими как str_replace(), strpos(), strstr()...

В Интернете полно дискуссий, например http://www.simplemachines.org/community/index.php?topic=175031.0