Оптимизация РНР: строки.
Недавно беседовал со знакомыми програмерами об оптимизации PHP. В ответ мне подкинули ссылочку, с пояснением что tony2001 является одним из разработчиков РНР. Забавно, что базовые функции РНР являются столь не продуманными и разработчики не желают обращать на это внимание.
Однако ради справедливости я решил провести ряд тестов, результаты которых немедленно ввергли меня в шок. Итак, дано: линукс, PHP/4.3.11, функцию бенчмарк которая измеряет скорость выполнения кода, и функцию внутри класса которая запускается 1 миллион раз (это конечно не самая наджная, но весьма показательная методика тестирования скриптов).
Задача: найти самый быстрый способ определения переменной которая будет состоять из других переменных.
<?
$a='a';
$s=implode('',array($a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," !!!"));
?>
Скорость работы PHP скрипта 18.0985 секунды.
Следующий по тормознутости вариант:
<?
ob_start();
echo $a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." !!!";
$s=ob_get_contents();
ob_end_clean();
?>
Скорость работы PHP скрипта 12.93 секунды.
Далее идет стандарт:
<?
$s=$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." !!!";
?>
Скорость работы PHP скрипта 9.73 секунды.
Следующий по тормознутости вариант:
<?
ob_start();
echo $a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," !!!";
$s=ob_get_contents();
ob_end_clean();
?>
Скорость работы PHP скрипта 9.12 секунды.
Столь любимый РНР програмерами способ включения переменных непосредственно в строку оказался самым быстрым.
<?
$s="$a $a $a $a $a $a $a $a $a $a !!!";
?>
8.88 секунды на цикл из 1 миллиона повторений.
Далее я изменил значение $a на строку длинной в 1099 байта, повторил тесты и получил абсолютно иную картину.
<?
ob_start();
echo $a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." !!!";
$s=ob_get_contents();
ob_end_clean();
?>
Скорость работы PHP скрипта 154.03 секунды.
<?
$s=$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." ".$a." !!!";
?>
Скорость работы PHP скрипта 108.77 секунды.
<?
$s=implode('',array($a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," !!!"));
?>
Скорость работы PHP скрипта 57.11 секунды.
<?
ob_start();
echo $a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," ",$a," !!!";
$s=ob_get_contents();
ob_end_clean();
?>
Скорость работы PHP скрипта PHP скрипта 41.30 секунды.
<?
$s="$a $a $a $a $a $a $a $a $a $a !!!";
?>
Скорость работы PHP скрипта 23.53 секунды.
Выводы:
- 1.Забудьте статьи об оптимизации PHP скриптов которые основывались на информации полученной до выхода PHP/4.3 (если среди советов было что-то: про использование одинарных кавычек вместо двойных, убирание коментариев из кода - скорее всего статья писалась очень давно и мало связана с реальностью).
- 2.Конкатенация (то что делается с помощью точки) в РНР 4.х (а возможно также в 5й и 6й версии) реализована отвратительно. Скорее всего это связанно с тем что РНР при каждой операции слияния создает временную переменную и на это уходит излишне большое количество ресурсов.
- 3.По возможности используйте включение переменных в строку заключенную в двойные кавычки, или используйте возможности echo со множеством агрументов.
P.S. Буду благодарен если кто нибудь повторит тесты на пятой версии РНР и опубликует здесь результаты. Сам пока на 5ю версию переходить не рискую.., имхо еще сыровата.., жду 5.3 
15 comments for “Оптимизация РНР: строки.”
//:
//samlowry
. з.ы. Кстати, кто нить встречал рускоязычных веб дизайнеров - специалистов по юзабилити? У меня в свое время создалось впечатление что в русском языке эти два понятия не совместимы.
//bog
//bogа сколько времени потребуется чтобы выполнить: <? $s='{$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} !!!'; ?> при прочих равных условиях? неплохо было бы эти значения отразить в статье...
//:ctсорри ошибся в коде (двойные кавычки вместо одинарных): <? $s="{$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} !!!"; ?>
//:ct<? $s='{$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} {$a} !!!'; ?> работает чуть медленее чем вариант когда фигурные скобки не используются.
//bog