Comments 52
А бенчмарки есть на странице официальной документации в самом первом комментарии от некоего Джона от ноября 2016 года.
Да, там нет разбора на опкоды. За это, конечно, спасибо.
двойные кавычки никогда не применяются без подстановки !
При прочих равных больше любим конкатенацию и одинарные, т.к. при простых переменных двойные еще норм, а вот необходимость вкрячивать фигурные в вариантах вида echo «test {$var}test» или echo «test {$a[1]}test» уже напрягает.
Жаль что этого варианта нет в статье, как впрочем и HEREDOC и банального выхода из интерпретатора вида ?> test<?=$var?>test Статья была бы полнее.
p.s.: Да и вообще шаблонизаторы рулят.
Жаль что этого варианта нет в статье, как впрочем и HEREDOC и банального выхода из интерпретатора вида ?> test<?=$var?>test Статья была бы полнее.
А там вообще никакой разницы во внутрянке — не о чем писать.
HEREDOC и "complex string" — это ровно те же строки в двойных кавычках (ROPE).
А выход из интерпретатора (и вход в него через <?=) — это просто отдельные операторы echo
Шаблонизация, предлагаемая PHP, уже давно не отвечает требованиям большинства современных веб-приложений, как минимум для ручной разработки (есть вариант кодогенерации) — прежде всего по требованиям безопасности. С другой стороны, сам язык и практики его применения давно переросли понятие "шаблонизатор", а некоторые надеются, что когда-нибудь шаблонизация в PHP будет если не полностью выпилена, то включаться принудительно в заданных разработчиком или админом случаях. Ну типа .php файлы это просто код, не требущий в начале <?php
, а только какой-нибудь .phtml — php шаблоны с ограниченной функциональностью.
Также было бы интересно узнать что быстрее — передать перечень аргументов одного типа, пользуясь splat оператором, или передать массив как один аргумент но с теми же значениями?
Все описанное ниже — это, по большей части, экономия на наносекундах
Автор использует весьма произвольно единицы измерения:
"Веревка" — 0.0129с = 12.9мс = 12900мкс = 12900000нс
"Конкатенация" — 0.0158 = 15.8мс = 15800мкс = 15800000нс
Разница в 2900000нс
А это уже экономия на миллионах наносекундах.
Ну и полемический прием «гипербола» никто не отменял. Кто же знал, что в полу-развлекательную статью понабегут зануды и начнут придираться к наносекундам? :)
Гм, а мне кажется, что это замедление нельзя делить на 71000. Код в цикле наверное парситься только раз и у замедления должна быть аддитивная составляющая.
Так что, будет ли замедление те же 40нс на строке если вращаем цикл 35500 раз и печатаем сразу 2 строки в цикле? Или вообще просто печатаем 71000 раз без цикла?
Код в цикле наверное парситься только раз и у замедления должна быть аддитивная составляющая.
Код парсится ровно один раз на этапе компиляции в опкоды и время это в замере не учитывается.
Набор опкодов же не меняется на каждой итерации, так что откуда взяться аддитивности?
Ну и в целом повторюсь — эта статья не про то, на сколько нано/микросекуд один вариант хуже другого, а про то, чем один вариант отличается от другого с точки зрения исполнения.
В 99% случаев использую одинарные и конкатенации.
P.S. Подчеркну, это НЕ для холивор, вопрос чисто из интереса.
1 - PHP_FUNCTION(user_sprintf)
1 + PHP_FUNCTION(user_printf)
2 2 {
3 3 zend_string *result;
4 + size_t rlen;
4 5 zval *format, *args;
5 6 int argc;
6 7
7 8 ZEND_PARSE_PARAMETERS_START(1, -1)
8 9 Z_PARAM_ZVAL(format)
9 10 Z_PARAM_VARIADIC('*', args, argc)
10 11 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
11 12
12 13 result = php_formatted_print(format, args, argc);
13 14 if (result == NULL) {
14 15 RETURN_FALSE;
15 16 }
16 - RETVAL_STR(result);
17 + rlen = PHPWRITE(ZSTR_VAL(result), ZSTR_LEN(result));
18 + zend_string_efree(result);
19 + RETURN_LONG(rlen);
17 20 }
foreach VS while VS for
Если будете это тестить, то хорошо бы сравнить в соответствующих кейсах с arrary_(map|reduce|filter), в идеале с разными вариантами callable. Сколько-то лет назад быстрейшим был foreach для массивов.
В случае функций стандартной библиотеки инлайнинг не пройдет. Так как они по сути своей интринсики, то это будет быстрый перебор хэш-таблицы внутри Си-функции (ZEND_HASH_FOREACH_KEY_VAL_IND
и т.д.) с вызовом на каждой итерации закешированного массива опкодов (zend_call_function(&fci, &fci_cache)
)
Глубоко не залезал, но, теоретически, действительно может работать быстрее за счет разницы в механизме итерирования. Надо изучать.
PHP. Фееричная расстановка точек над кавычками