Оптимизация РНР-сценариев. Часть 4. Регулярные выражения

Регулярные выражения

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

В качестве примера рассмотрим поиск 10 000 случайных строк, в которых встречается любая комбинация из трех символов от «а» до «g» (то есть «agb», «bbb», «cab» и так далее).
Будут сравниваться два варианта решения с применением регулярных выражений, осуществляемых с помощью функций егед () и preg_match (). Давайте начнем с кода, который должен решить задачу с помощью функции егеg ():


for($i = 0; $i < 10000; $i++) {
   if(ereg(".*[abcdefg]{3}.*", $strings[$i])) {
    $found++;
  }
 }

Эту же задачу можно решить с помощью функции preg match ():


for($i = 0; $i < 10000; $i++) {
  if(preg_match("/.*[abcdefg]{3}.*/", $strings[$i])) {
   $found++;
  }
 }

Если сравнить продолжительность работы этих двух методов (ereg () — это метод  #1, a pregmatch () — это метод #2), получим следующие результаты:

  • Метод #1 занял 0.21848797798157 секунд.
  • Метод #2 занял 0.15077900886536 секунд.
  • Метод #2 был быстрее метода #1 на 30.99%

Как видите, метод #2 (preg_match()) работал примерно на 30% быстрее, чем метод с использованием ereg (). Вообще, вы увидите, что функции preg_* всегда обрабатывают тексты быстрее, чем их аналоги ereg ().

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

Особенно это относится к поиску или замене строковых констант. Чтобы продемонстрировать это на примере, рассмотрим профили preg_match() и strst r () для подсчета количества строк, содержащих подстроку j j j .

Совет. Как сделать в WordPress вывод популярных записей по количеству просмотров.

Для первого метода мы будем использовать регулярное выражение и функцию preg_match (), подобную той, которая применялась в предыдущем примере:

 for($i = 0; Si < 10000; $i++) {
   if(pregjnatch("/.*jjj.*/i" , $strings[$i]) ) (
   $found++;
  }
 }

В качестве второго метода мы будем использовать функцию strst r () , которая производит поиск константной подстроки в строке:

 for($i = 0; $i < 10000; $i++) {
  if(strstr($strings[$i], "jjj")) {
    $found++;
  }
 }

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

  • Метод #1 занял 0.11128091812134 секунд.
  • Метод #2 занял 0.05986499786377 секунд.
  • Метод #2 был быстрее метода #1 на 46.20%

Очевидно, что при увеличении производительности на 46% одного из регулярных выражений настоятельно рекомендуется использовать стандартные РНР-функции для работы со строками всегда, когда это возможно.

Если вы интересуетесь XML, то можете ознакомиться как сделать xml parser.

PS. А всем блоггерам рекомендую правильно настроить .htaccess на свой сайте