PHP: красота кода сказывается на производительности
Читабельный код выполняется медленнее
Недавно я для себя открыл, что PHP не умеет оптимизировать код, а тут новый удар: оказывается, что красота кода отрицательно влияет на производительность. Как и в прошлый раз, для проверки гипотез использовался Vulcan Logic Disassembler. Сравнивались два куска кода: Тест №1: <?php $a = true; if (true == $a) { print 1; } ?> и [...]
← Вернуться к полной версии записи «PHP: красота кода сказывается на производительности»…
Автор: Vladimir; опубликовано в: PHP; метки: eAccelerator, PHP, оптимизация, производительностьСен
2009
Комментарии к статье «PHP: красота кода сказывается на производительности» (11) »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «PHP: красота кода сказывается на производительности»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.


Одно обидно: из eAccelerator 0.9.6-rc1 выкинули оптимизатор и кучу всего остального, оставив только кэширование опкода.
Интересно протестировать связку APC + optimizer.
Ну спички же форменные. Да и как это будет сказываться на «производительности» самого интерпретатора?
Спички спичками, но есть несколько нюансов:
Вообще мне на ум приходит сравнение программ, скомпилированных Turbo Pascal 7.0 и Borland C++ 3: в Turbo Pascal оптимизатор отсутствует в принципе, а в BC++ его можно включить. Разница ощутима.
Я натравил оптимизатор на устаревшую локальную копию своего блога (интерпретатор обломался где-то после загрузки плагинов) и сравнил размер выдачи VLD:
Разница (для не полностью загруженного WP) составляет 3,421 опкод. Полагая, что опкод выполняется 0.5 микросекунды (думаю, что для дешевых VPS это где-то рядом), имеем разницу в 1.7 миллисекунды. На полностью загруженном WordPress разница будет видна сильнее. Использование оптимизатора — бесплатный способ снизить нагрузку на сервер.
Положительно. Компиляция и оптимизация будут выполнены один раз, после чего результат будет закэширован в shared memory.
[...] « PHP: красота кода сказывается на производительности [...]
Почему вы считаете, что
5 PRINT
6 FREE
работает медленнее
5 ECHO
?
в остальных рассуждениях подобный косяк повторяется.
Очевидно потому, что копался во внутренностях Zend Engine.
Во-первых, лишний опкод производительности не добавляет (из-за издержек на его анализ/выполнение).
Во-вторых, внутренняя реализация
printвызываетecho, из-за чегоprintне может быть быстрее:{
zend_op *opline = EX(opline);
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;
return ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
В-третьих, оптимизаторы неспроста
PRINT/FREEпреобразовывают вECHO.Вы меня не поняли и забавно реагируете.
Никто не утверждал, что лишний опкод добавляет производительность, но вовсе не факт, что print + free выполняется медленнее, чем echo. Я пишу о том, что рассуждение о скорости глядя на внутренние опкоды php, которые вызывают функции, без приведения листингов этих функций бессмысленно. Вот еще пример:
«Конкатенация или переменные внутри строки»
CONCAT
CONCAT
и
INIT_STRING
ADD_STRING
ADD_VAR
ADD_STRING
Можно предположить, что второй блок выполняется медленне, но утверждать этого нельзя.
Приведённая цитата на Си вообще непонятно, как относится к вопросу.
Про оптимизаторов довод единственно-хороший, но я впервые слышу это утверждение, а никаких ссылок в вашем сообщении нет.
Ну почему же? Внутренняя реализация
printвызывает внутреннюю реализациюecho. Уже только поэтомуprintне может быть быстрее. Ну и еще необходимость выполненияFREE.Эм… Листинг обработчиков опкодов занимают порядка мегабайта. На мой взгляд, приводить их несколько нецелесообразно. Тем более, что в них интенсивно используются внутренние макросы Zend Engine, которые не всегда очевидны.
Если Вы познакомитесь с Zend Engine поближе, то можно
INIT_STRINGвыделяет один байт памяти и создаёт строковую переменную.ADD_STRINGвызывает функциюadd_string_to_string().ADD_VARпреобразует переменную в строку и вызывает ту жеadd_string_to_string().CONCATвызывает функциюconcat_function(), которая по функциональности эквивалентнаADD_VAR(с той разницей, чтоconcat_function()не производит действий, характерных для обработчика опкода).Что
concat_function(), чтоadd_string_to_string()— это, по сути,erealloc()+memcpy().В первом случае получаем два распределения памяти и копирования, во втором — три (это не считая выделения однобайтового буфера). Плюс во втором случае получаем два лишних опкода, которые, к тому же, занимают место в памяти (причём нельзя сказать, что очень мало).
Видите? Если бы я приводил код всех обработчиков, было бы мало смысла
Та цитата показывает, что обработчик
PRINTсоздаёт целочисленную переменную (возвращаемое значение) и вызывает обработчикECHO. Но с используемыми именами макросов это не очевидноВсё-таки Вы невнимательно читали:
Ну и плюс листинги.
[...] оптимизатор, встроенный в eAccelerator, то можно повысить производительность PHP-кода. Анализ производительности MySQL-запросов и знание [...]
Владимир!))) молодец, четко все расписал, как в статье так и в каментах))