оптимизация скорости preg_replace

Рассматривая принятый ответ об изъятии всех символов из строки, оставляя числа , автор добавил a + после выражения

 $str = preg_replace('/[^0-9.]+/', '', $str); 

чтобы найти подстроки, а не отдельные вхождения, для удаления. Для функциональности опция + является необязательной. Но я начал задаваться вопросом, является ли добавление + быстрее или нет. (Или нет никакой разницы?)

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

Поэтому, когда вы используете эту технику для удаления подстрок, нужно попытаться найти большие или маленькие подстроки?

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

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


 функция tst ($ pat, $ str) {
     $ start = microtime (true);
     preg_replace ($ pat, '', $ str);
     return microtime (true) - $ start;
 }
 $ strs = array (
     'letters' => str_repeat ("a", 20000),
     'numbers' => str_repeat ("1", 20000),
     'most_letters' => str_repeat ("aaaaaaaaaaaaa5", 20000),
     'most_numbers' => str_repeat ("5555555555555a", 20000)
 );
 $ pats = array (
     'rep' => '/[^0-9.]+/',
     'norep' => '/[^0-9.]/'
 );

 // прекомпиляция шаблонов (php кэширует их для каждого скрипта) и разминки
 микропоры (истина);
 preg_replace ($ pats ['rep'], '', 'foo');
 preg_replace ($ pats ['norep'], '', 'foo');

 foreach ($ strs as $ strname => $ str) {
     echo "$ strname \ n";
     foreach ($ pats as $ patname => $ pat) {
         printf ("% 10s% .5f \ n", $ patname, tst ($ pat, $ str));
     }
 }

Я провел несколько тестов скорости, как предложил Крис . По сравнению с его кодом я:

  • добавлено str_replace для сравнения:
 $ str_replace_array = array ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.');

 функция tst ($ pat, $ str) {
     глобальный $ str_replace_array;
     $ start = microtime (true);
     if ($ pat == '')
         str_replace ($ str_replace_array, '', $ str);
     еще
         preg_replace ($ pat, '', $ str);
     return microtime (true) - $ start;
 } 
  • сделал все строки одинаковой длины, поэтому результаты можно было бы сравнить лучше

Результаты в:

 letters rep 0.00298 norep 0.06953 str_replace 0.00406 numbers rep 0.02867 norep 0.02612 str_replace 0.01242 mostly_letters rep 0.00931 norep 0.06649 str_replace 0.00593 mostly_numbers rep 0.03285 norep 0.02942 str_replace 0.01359 

Он показывает, что повторяющееся регулярное выражение (с добавлением + ) происходит намного быстрее при замене больших блоков (меньше обработки памяти?). Но повторное регулярное выражение немного быстрее, если не нужно много заменять.

Кроме того, str_replace в основном всегда быстрее (в два раза быстрее), чем замена регулярного выражения, за исключением случаев, когда регулярное выражение соответствует полной строке.

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