» » Оптимізація РНР-сценаріїв. Частина 4. Регулярні вирази

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

Однією з найбільш поширених помилок оптимізації, що допускаються РНР розробниками, є надмірне або неправильне використання регулярних виразів в PHP-сценаріях . У порівнянні з іншими операціями, пов'язаними з роботою з текстом, регулярний вираз є найдорожчою операцією, яка тільки може бути виконана. Тому будь-яке використання регулярних виразів має супроводжуватися з великою обережністю.

Як приклад розглянемо пошук 10 000 випадкових рядків, в яких зустрічається будь-яка комбінація з трьох символів від «а» до «g» (тобто «agb», «bbb», «cab» і так далі).
Будуть порівнюватися два варіанти вирішення із застосуванням регулярних виразів, здійснюваних за допомогою функцій егеg() і 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 () для підрахунку кількості рядків, що містять підрядок jjj.

Для першого методу ми будемо використовувати регулярний вираз і функцію 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% одного з регулярних виразів наполегливо рекомендується використовувати стандартні РНР-функції для роботи з рядками завжди, коли це можливо.


624 12.01.14



Напівжирний Нахилений текст Підкреслений текст Перекреслений текст | Вирівнювання по лівому краю По центру Вирівнювання по правому краю | Вставка смайликів Вибір кольору | Прихований текст Вставка цитати Перетворити вибраний текст з транслітерації в кирилицю Вставка спойлеру