Pull to refresh

Comments 52

Ну вообще, вывод 1 прямо спрашивается на ZCE — это считается рекомендуемой практикой.
Однако это довольно часто встречающееся заблуждение. Да и цель статьи в том, чтобы показать «почему это так», а не сказать «делайте так, поверьте на слово» ;)
Не соглашусь — такая штука была серьёзно распространена во времена php4 и там далеко не всё так было просто. В всех более-менее современных гайдах уже пишут про различие.

А бенчмарки есть на странице официальной документации в самом первом комментарии от некоего Джона от ноября 2016 года.

Да, там нет разбора на опкоды. За это, конечно, спасибо.
Разница больше стилистическая. Удобно по кавычкам сразу понимать — есть там подстановка или нет, особенно если строка длинная.
Именно так, у нас принято такое соглашение для стиля кодирования:
двойные кавычки никогда не применяются без подстановки !
UFO just landed and posted this here
а как же
user@aaa:/var/log/nginx$ php7.0 -a
Interactive mode enabled

php >
php >
php > echo '\n';
\n
php > echo "\n";

php >
Так делать не стоит, для переносов строк лучше использовать свою или системную константу PHP_EOL
… что будет весьма неудобно если их больше одной в строке, и не имеет смысла если нужно именно \n (а не то что по дефолту в системе).
Всегда использую PHP_EOL, DIRECTORY_SEPARATOR и прочие константы, и тут неважно быстрее или медленнее — просто так правильнее.
С другой стороны, гораздо удобнее искать строки в коде, если все кавычки одинаковы, причём независимо от языка.
Мне кажется, что с оглядкой на подсветку синтаксиса — это несколько надуманная проблема. (собственно как и описанная в посте, на который вы отвечали)
Я о задачах типа «вот тут сообщение об ошибке вывалилось — надо найти откуда оно вообще» или «вот тут у нас надпись — надо изменить» при слабом знакомстве с кодовой базой. А в случае PHP ещё может быть callable со строковым референсом на класс, функцию, метод. И если с классом решается использованием ::class, то с функциями методами такого нет.
Сначала я, особо не вдумываясь, решил, что вполне себе здравый аргумент. Но что-то все равно «царапало» глаз. Начал прикидывать и вот не удалось мне придумать как единообразие кавычек спасет в данной ситуации. Не могли бы раскрыть тему, может я просто что-то не правильно понял?

К примеру если по коду надо найти строку function. Если просто набрать, то в выборке будет много function, которые относятся к описанию функций. Т.о. проще искать 'function, но, т.к. вариантов кавычек может быть два, надо не забыть поискать и по "function

Выше правильно ответил BoShurik, единственно можно ещё искать по регулярке типа ['"]function В любом случае проще искать только по "function, не думая про 'function

echo 'test ',$var,'test'; имеет тот недостаток, что его по быстрому не заменишь на переменную $a='test ',$var,'test'; — придется переправлять запятую на точку.

При прочих равных больше любим конкатенацию и одинарные, т.к. при простых переменных двойные еще норм, а вот необходимость вкрячивать фигурные в вариантах вида 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 оператором, или передать массив как один аргумент но с теми же значениями?
UFO just landed and posted this here
UFO just landed and posted this here
Все описанное ниже — это, по большей части, экономия на наносекундах

Автор использует весьма произвольно единицы измерения:


"Веревка" — 0.0129с = 12.9мс = 12900мкс = 12900000нс
"Конкатенация" — 0.0158 = 15.8мс = 15800мкс = 15800000нс


Разница в 2900000нс


А это уже экономия на миллионах наносекундах.

Все же имелось в виду «за операцию». Разделите на 71.000 и их окажется всего 40.

Ну и полемический прием «гипербола» никто не отменял. Кто же знал, что в полу-развлекательную статью понабегут зануды и начнут придираться к наносекундам? :)

Гм, а мне кажется, что это замедление нельзя делить на 71000. Код в цикле наверное парситься только раз и у замедления должна быть аддитивная составляющая.


Так что, будет ли замедление те же 40нс на строке если вращаем цикл 35500 раз и печатаем сразу 2 строки в цикле? Или вообще просто печатаем 71000 раз без цикла?

Код в цикле наверное парситься только раз и у замедления должна быть аддитивная составляющая.

Код парсится ровно один раз на этапе компиляции в опкоды и время это в замере не учитывается.
Набор опкодов же не меняется на каждой итерации, так что откуда взяться аддитивности?

Ну и в целом повторюсь — эта статья не про то, на сколько нано/микросекуд один вариант хуже другого, а про то, чем один вариант отличается от другого с точки зрения исполнения.
Если самое узкое место в вашем коде на PHP — это конкатенации строк, то у вас есть проблемы посерьёзнее, чем выбор между одинарными и двойными кавычками ;)
Указывайте версию php которую разбираете. Так-то в 5-ке даже implode работал быстрее конкатенации.
Вот умеете уговорить! :)

В 99% случаев использую одинарные и конкатенации.

Обычно в банковских блогах я ожидаю увидеть информацию о Java или .NET. Поэтому стало любопытно — для каких целей в АльфаБанке используется PHP?

P.S. Подчеркну, это НЕ для холивор, вопрос чисто из интереса.
Да ну бросьте, какой тут может быть холивар!?
Полуофициально используется для внутренних нужд IT, когда есть нужда упростить/автоматизировать некритичный, но занудный процесс — например формирование заявок на мониторинг.
Шел 2019 год, а phpшники все еще спорили о кавычках…
Потому, что можем! :D
Если есть из чего выбирать, то грех про этот выбор не поспорить.
То же, что и по поводу printf, только echo отдельно. Алгоримт генерации конечной строки тот же самый.
diff: user_sprintf vs user_printf
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	  }

Конкатенация удобнее, чисто с точки зрения подсветки переменных и автоматизированного рефакторинга в IDE. Экономия на «веревках» не стоит неудобств
А если там метод какой? Или элемент массива? Мне вот лень в {} это все оборачивать

Ну так здравый смысл то никто не отменял.


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

foreach VS while VS for

Если будете это тестить, то хорошо бы сравнить в соответствующих кейсах с arrary_(map|reduce|filter), в идеале с разными вариантами callable. Сколько-то лет назад быстрейшим был foreach для массивов.

Логично, что foreach быстрее. В arrary_(map|reduce|filter) вызывается функция на каждую итерацию.
Ну, оптимизацию, которая инлайнит тело функции легко представить, особенно если функция анонимная, то есть используется только здесь.

В случае функций стандартной библиотеки инлайнинг не пройдет. Так как они по сути своей интринсики, то это будет быстрый перебор хэш-таблицы внутри Си-функции (ZEND_HASH_FOREACH_KEY_VAL_IND и т.д.) с вызовом на каждой итерации закешированного массива опкодов (zend_call_function(&fci, &fci_cache))


Глубоко не залезал, но, теоретически, действительно может работать быстрее за счет разницы в механизме итерирования. Надо изучать.

Sign up to leave a comment.