Тест 2х функций замены: str_replace vs preg_replace

Всем имеющим отношение к программированию на php хорошо знакомы эти 2 функции.
Первая предназначена для замены заданного фрагмента текста на другой, синтаксис:

mixed str_replace( mixed search, mixed replace, mixed subject [, int &count] )

Вторая производит аналогичные действия с той лишь разницей, что в качестве параметров мы можем использовать регулярные выражения.
В каждом учебном пособии по PHP рекомендуется для простых замен использовать str_replace() в целях экономии ресурсов и времени.
На блоге ParserPRO в теме про парсинг выдачи Google у меня с владельцем блога возникли небольшие разногласия по поводу неэффективного использования preg_replace в его скрипте на что автор ответил небольшим тестом производительности этих 2х функций. Результаты получились вполне логичные, str_replace обогнал preg_replace в простом случае в 2 раза, чего и следовало ожидать…
Но я решил тоже провести эксперимент. Причем немного более детальный, в 2 этапа.

Первый этап аналогичен эксперименту ParserPRO.

1 этап

Код по замеру скорости для str_replace:

<?php
//test_str.php
define('START', microtime(TRUE));
$text="Почему я делаю это?\r\nНе знаю, но это весело!\r\nВедь надо же стать легендой )";

$text = str_replace(array("\n", "\r", "\t"), '', $text);
$time = microtime(TRUE) - START;
echo $time;
$hFile = fopen('test_str.txt','a');
fwrite($hFile, $time."\r\n");
fclose($hFile);
?>

в примере ParserPRO был задействован class Timer для определения времени работы скрипта, я решил воздержаться от использования ООП и применил функцию microtime(), которая возвращает текущее время в микросекундах.

Код по замеру скорости для preg_replace:

<?php
//test_preg.php
define('START', microtime(TRUE));
$text="Почему я делаю это?\r\nНе знаю, но это весело!\r\nВедь надо же стать легендой )";

$text = preg_replace("/[\n\r\t]/", '', $text);
$time = microtime(TRUE) - START;
echo $time;
$hFile = fopen('test_preg.txt','a');
fwrite($hFile, $time."\r\n");
fclose($hFile);
?>

Для каждой функции скрипт запускался 30 раз.

Результаты 1го этапа

Время str_replace:

2.50339508057E-5
2.59876251221E-5
2.59876251221E-5
2.38418579102E-5
2.50339508057E-5
0.000259876251221
0.000288963317871
2.38418579102E-5
0.000140905380249
9.3936920166E-5
2.50339508057E-5
2.50339508057E-5
0.000241994857788
0.000216960906982
2.78949737549E-5
2.78949737549E-5
0.000187873840332
0.000251054763794
2.50339508057E-5
2.38418579102E-5
2.69412994385E-5
2.69412994385E-5
2.69412994385E-5
2.69412994385E-5
2.88486480713E-5
0.000158071517944
2.47955322266E-5
2.59876251221E-5
2.59876251221E-5
0.000152111053467

Время preg_replace:

0.000158071517944
5.19752502441E-5
5.00679016113E-5
0.000127077102661
5.00679016113E-5
5.00679016113E-5
5.10215759277E-5
0.000157117843628
8.79764556885E-5
4.88758087158E-5
5.10215759277E-5
5.10215759277E-5
0.000156879425049
0.00028395652771
5.10215759277E-5
5.00679016113E-5
5.10215759277E-5
5.00679016113E-5
5.19752502441E-5
5.00679016113E-5
5.29289245605E-5
8.39233398438E-5
0.000102996826172
0.000205993652344
5.10215759277E-5
5.10215759277E-5
0.000114917755127
0.000109910964966
4.88758087158E-5
5.00679016113E-5

Итого получаем следующие средние арифметические значения (в микросекундах):

str_replace: 8.3653132E-5
preg_replace: 8.503596E-5

Результаты для меня прямо скажу нелогичные и неожиданные. str_replace лишь на какие-то доли опередил preg_replace.

2 этап я решил загрузить функции более серьезным текстом для чего взял 10 параграфов текста Lorem Ipsum.

Результаты 2го этапа

Время str_replace:

7.10487365723E-5
7.79628753662E-5
0.000244855880737
0.000202894210815
0.000128984451294
6.79492950439E-5
0.000123023986816
7.00950622559E-5
6.79492950439E-5
6.89029693604E-5
7.10487365723E-5
7.10487365723E-5
7.20024108887E-5
7.29560852051E-5
7.10487365723E-5
6.98566436768E-5
6.89029693604E-5
7.10487365723E-5
7.20024108887E-5
7.20024108887E-5
0.000108003616333
0.000148057937622
7.5101852417E-5
7.39097595215E-5
0.000130891799927
0.000211000442505
0.000202894210815
7.20024108887E-5
0.000131845474243
7.00950622559E-5

Время preg_replace:

0.00218296051025
0.00223302841187
0.00291705131531
0.00217604637146
0.00236797332764
0.00270104408264
0.0027129650116
0.0022349357605
0.00225400924683
0.00253701210022
0.00287103652954
0.00218892097473
0.00223994255066
0.00217390060425
0.00218105316162
0.00240588188171
0.00285792350769
0.00233006477356
0.00221300125122
0.00267910957336
0.00231385231018
0.00262093544006
0.00287890434265
0.00221490859985
0.00269603729248
0.00248193740845
0.00217890739441
0.0021538734436
0.00244498252869
0.00218296051025

Второй этап расставил все по местам:

str_replace: 0.000101979574
preg_replace: 0.002421498299

В этом случае str_replace обогнал preg_replace почти в 24 раза.

Условия тестирования

  • Apache2
  • PHP5
  • Acer Extensa 5510 Core 2 Duo 1.66 Ghz, 1 Gb RAM

    Добавить в закладки
    google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

    Понравился пост? Почему бы не оставить комментарий, или подписаться на мой фид и получать обновления автоматически?.

    Трэкбэки & Пингбэки

    Нет трэкбэков/пингбэков

    Комментарии

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

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

    Респект вам за тест!

    ParserPRO, Acer - не самая брендовая и бредовая ( ;) ) марка, но данная модель меня вполне пока устраивает, ну да ладно.
    Текст брался с http://www.lipsum.com/ (10 параграфов). Второй этап теста меня вовсе не удивил. Обычные сишные функции по любому будут быстрее недетерминированных конечных автоматов.

    Полностью согласен с [YS.PRO] по поводу str_replace, зачем лить в машину 98 бензин и переплачивать, если можно вполне отлично на 95 ездить…

    Ну смотрите. По поводу Асера я вас предупредил. Так что потом пинать будете только на себя!

    “недетерминированных конечных автоматов”
    А это что такое? Я таких магических слов не знаю :))))

    Итак, детерминированным конечным автоматом (ДКА) называется устройство, описываемое следующими параметрами:
    Q – конечное множество состояний
    Σ – конечное множество входных символов.
    δ – функция перехода. Аргументы – состояние и входной символ, результат – состояние.
    q0 – начальное состояние, принадлежит Q
    F – множество допускающих состояний, является подмножеством Q.

    Функционирует ДКА следующим образом:
    Автомат начинает работу в состоянии q0.
    Если автомат находится в состоянии qi, а на вход поступает символ b, то автомат переходит в состояние δ(qi, b).

    Работа ДКА заключается в распознавании цепочек символов, принадлежащих множеству Σ. Если, обработав цепочку, автомат оказался в допускающем состоянии, то цепочка считается допущенной, если нет, то нет. Таким образом, ДКА задаёт некоторый язык – множество допускаемых им цепочек, алфавит этого языка – множество Σ.

    Определение недетерминированного конечного автомата (НКА) практически полностью повторяет приведённое выше определение ДКА. Отличий всего два:
    δ – функция перехода. Аргументы – состояние и входной символ, результат – множество состояний (возможно – пустое).
    Если автомат находится в состоянии qi, а на вход поступает символ b, то автомат переходит во множество состояний δ(qi, b). Если автомат находится во множестве состояний {qi}, то он переходит во множество состояний, получаемое объединением множеств δ(qi, b).
    НКА тоже распознаёт цепочки символов, цепочка считается допустимой, если после её обработки множество состояний, в котором оказался автомат, содержит хотя бы одно допускающее. Таким образом, НКА также задаёт некоторый язык.
    взято с RSDN

    Сложно все это… POSIX регулярные выражения являются детерминированными конечными автоматами, в то время как PCRE - НКА.

    P.S.: ParserPRO, у меня был монитор SONY профессиональный, для дизайнеров. Проработав всего 5 лет пропал красный цвет. Ничего подумал я и повез на диагностику, там парни сразу сказали, что ничего страшного, посмотрим, проводок видно отошел… Бренд не давал никакого намека в мыслях, что Trinitron может сломаться. Спустя несколько дней мне позвонили и удивленным голосом сказали, что полетел кинескоп. Вот… Я не защищаю Acer, просто говорю о том, что всякое бывает в жизни.

    Боже, какие умные слова!!!! RSDN как всегда на высоте :)) Хотя могли бы и своими словами рассказать, мы же не ученые, чтобы перекидываться официальными описаниями.

    Решил повторный тест не проводить, так как посчитал, что его результаты не принесут ничего интересного и важного.

    Чтобы рассказать своими словами надо быть достаточно аудированным в автоматах…

    Сразу прошу прощения за оффтопик.
    У вас слетело «Облако тэгов».
    На теге «PHP» видим ссылку: «http://ys-pro/tag/php»
    Я, конечно догадался «дописать» dot COM, но это наверно все-таки не правильно:)

    Большое спасибо, исправил.

    Так скорость preg_replace будет еще зависеть(падать) и от сложности регулярного выражения и его кривости.

    Вообще-то скорость ВСЕГДА зависит от сложности регулярного выражения :)))

    Всем советую почитать классический труд Джеффри Фридла - Регулярные выражения.

    Оставить комментарий

    (required)

    (required)