Comments 58
Получается, что на небольших объёмах правильным решением чаще будет добавление железа
Очень важное и правильное замечание. Многие крупные компании забывают об этом и твердят об оптимизации. Именно поэтому иногда натыкаешься на разработчиков, которые до сих пор двойные кавычки в одинарные переводят ради увеличения скорости.
На своем примере в этом убедился. Когда у вас нет зоопарка серверов проще докупить мощности, особенно в наше время облаков.
Именно поэтому иногда натыкаешься на разработчиков, которые до сих пор двойные кавычки в одинарные переводят ради увеличения скорости.
Зачастую это делается для того, чтобы потом не огрести проблем. Ну и потом уже по привычке не ставят их там, где это просто не нужно.
А если рассматривать с точки зрения производительности — никаких отличий по скорости в двойных и одинарных кавычках нет (если без интерполяции). Более того, даже если использовать конкатенацию — это так же соберётся в один php-опокод. А если это будет ещё и константа, то соберётся на этапе раннего статического связывания.
TL:DR; За этот год уже 3 вопроса на Тостере было, где используют двойные кавычки, а внутрь случайно прилетает управляющая конструкция. А вопрошающие просто не понимают «почему не работает».
В любом случае, микрооптимизации работают только если у вас действительно крупный проект. В остальном надо либо искать узкое место (а зачастую оно есть), либо просто наращивать мощность.
С другой стороны, если мы выяснили, что между одинарными и двойными кавычками отличий по скорости в константных выражениях нет (можно самостоятельно убедиться в этом, воспользовавшись vld), то не думали вы, что опытные разработчики могут по какой-либо иной причине не использовать двойные кавычки?
Ну вот на вскидку:
1) Интерполяция нечитаема без подсветки и статического анализа кода (хотя кто в своём уме будет работать в nano — я не знаю).
2) Интерполяция работает в PHP через одно место (только с переменными, никаких выражений).
3) Сложнее рефакторить, нежели конкатенацию.
Примеры все, конечно, высосаны из пальца, но если посмотреть на это как на комплекс проблем, против решений, где проблем никаких нет, кроме пары лишних символов (ну или функций, для любителей sprintf), то кажется, что это всё не просто так. Что думаете?
Стоп. Я не говорил, что не нужно использовать двойные кавычки :)
Я лишь говорил, что не нужно везде заменять двойные на одинарные с целью сделать мегабыстрыйсуперхайлоад сайт. Не получится.
А применять их по делу — да они для этого и были созданы, почему бы и нет.
" string {$var1} string {$var2}"
?Так вот, конкатенация медленее и, по моим тестам, как бы не на 30%
Под интерполяцией понимается: " string {$var1} string {$var2}"?
Не «понимается». Это общеизвестный термин: www.google.com/search?q=интерполяция+строк Так что да
Так вот, конкатенация медленее и, по моим тестам, как бы не на 30%
Ответ: Зависит от того, в какой момент собираются эти инструкции.
<?php
$var = 42;
echo 'some' . $var . 'any';
/**
* line #* E I O op fetch ext return operands
* -------------------------------------------------------------------------------------
* 2 0 E > ASSIGN !0, 42
* 4 1 CONCAT ~2 'some', !0
* 2 CONCAT ~3 ~2, 'any'
* 3 ECHO ~3
* 5 4 > RETURN 1
*/
<?php
$var = 42;
echo "some${var}any";
/**a
* line #* E I O op fetch ext return operands
* -------------------------------------------------------------------------------------
* 2 0 E > ASSIGN !0, 42
* 4 1 ROPE_INIT 3 ~3 'some'
* 2 ROPE_ADD 1 ~3 ~3, !0
* 3 ROPE_END 2 ~2 ~3, 'any'
* 4 ECHO ~2
* 5 5 > RETURN 1
*/
И тут просто всё зависит от скорости выполнения инструкций. Но делаем ход конём и переносим конкатенацию на этап раннего статического связывания. И вуаля!
<?php
class Wtf
{
public const VAR = 42;
public const CONCAT = 'some' . self::VAR . 'any';
}
echo Wtf::CONCAT;
/**
* line #* E I O op fetch ext return operands
* -------------------------------------------------------------------------------------
* 2 0 E > NOP
* 8 1 ECHO 'some42any'
* 10 2 > RETURN 1
*/
Тут даже самому рассеянному станет очевидно, что конкатенация будет на порядки быстрее, потому что интерполяция умеет только в позднее связывание и просто не умеет работать на уровне этапа компиляции в инструкции, а только во время интерпретации.
Причём это относится не только к константам, но и полям, объявленным на раннем этапе:
class Wtf2
{
private $some = 'asdasd' . 42 . 'asdasd';
}
Они тоже содержат только одну инструкцию фетча переменной, а константное значение уже заранее помещается в таблицу символов интерпретатора.
Но делаем ход конём и переносим конкатенацию на этап раннего статического связывания
То, что константа будет намного быстрее (фактически мгновенно) — это очевидная вещь, которую даже не стоит упоминать!
Тем не менее, как часто в практических задачах удается перенести то не знаю что на уровень констант.
P.S. На моем, совершенно синтетическом тесте (1 млн. итераций)
"Some string contains {$x} and {$y} with {$z} string";
1.7375 sec'Some string contains ' . $x . ' and ' . $y . ' with ' . $z .' string'
2.2438 secsprintf("Some string contains %s and %s with %s", $x, $y, $z)
1.9559 secКонечно это были экстремальные тесты и в реальности почти никто не отключает сборку мусора в пхп и ноде. Мои "helloword тесты" показали, что нода сравнима по скорости с пхп. Сейчас для достижения таких результатов нужно использовать swoole/workerman вместо php-fpm, а в php 8 так будет работать «из коробки».
А вы представьте сколько потребуется человеко-часов, чтоб переписать всю кодовую базу такого проекта. Придется нанять гору программистов Go, снять/расширить помещение, платить им. А пока они будут творить, текущих код должен кто то поддерживать.
Ну, короче, много всего может быть. Можно попросить, конечно, скинуть бадушников код, чтобы разобраться, но не думаю что они это сделают :)
Ну и в конце концов есть функционал «под капотом», о котором непосвящённый просто не догадывается. Всякий ML, файрволлы от спамеров и прочее-прочее.
Да и не стоит, хм, сарказмировать (а есть такое слово? о__0). Есть как бы и биндинги на tensorflow, например. Есть куча всяких библиотек под ML. Да и PHP будет побыстрее того же классического Python и большинства других интерпретаторов.
Да, мы используем обученные модели из PHP.
Благодаря Pinba за их потреблением легко следить — сейчас это сотые доли процента кластера.
Я вижу три варианта: php-opencv (сыро), php-tensorflow (нужен php 7.3 RC) и php-ml (медленно).
Но я думаю, вы используете что-то другое. Было бы интересно узнать что именно :)
Это как в анекдоте про секретаршу:
Устраивается девушка на работу. «Я печатаю 2000 знаков в минуту!» (в сторону) «Такая фигня получается!»
— авторизуется пользователь
— подтягивается его сессия
— проверяется на флуд запросами
— отправляются единицы/десятки запросов в различные сервисы для учета статистики работы различных сервисов, апи, и так далее
— выполняется собственно бизнес-логика, которая может представлять из себя походы в сотни разных сервисов, с разными проверками и обработкой краевых случаев, которые нигде, кроме как в хайлоаде себя бы не проявляли
— и т.д.
Статику можно отдавать 50к qps и с одной машины, а вот для запросов в апи вам нужно не только те 600 (вероятно, всё же чуть меньше) серверов, но и как минимум столько же серверов с MySQL, довольно много серверов для сервисов (уверен, тоже как минимум сотни, если не тысячи), и так далее. Сравнение с ноутбуком здесь выглядит немного неуместным :). Вы можете написать сервис, который работает с вашего ноутбука и обслуживает большой QPS, только делать он скорее всего будет что-то очень простое и вряд ли кому-то очень нужное :).
кстати, интересно было бы почитать ваши мысли от php в баду и php в вк =)
Кэширует скрипты целиком в виде бинарника и при обращении к скрипту не трати время на его копиляцию.
Тогда на некторых скриптах скорость удвоилась. Но основная проблема была в БД поэтому про оптимизацию PHP потом забыл.
сейчас это уже в ядре
Для того чтобы увеличить мощность в полтора раза, нам нужно добавить 300 серверов.
Хмм. Насколько знаю, добавление нового сервера не дает прироста в 100%, там формула вроде: 1 / (1 — n), где n — это количество серверов. То есть, в какой-та момент времени мы дойдем до такой степени, что новой сервер не даст производительности.
Переход на какой-нибудь swoole нереален, а вот промежуточное решение типа roadrunner как раз может быть очень привлекательным. Хотелось бы только конкретных цифр, в чем выиграли в чем проиграли.
RoadRunner не пробовали.
У нас есть места, на которых подобный инструмент может дать прирост и на которых не сложно поэкспериментировать, — возможно в ближайшем будущем попробуем.
В любом случае, целиком на него переписать наш код очень сложно, выигрыш не будет сопоставим с затратами. С нуля это сделать проще, но даже в таком случае нужно постоянно держать в голове, что ничего не должно оседать в глобальном скоупе, кеши должны инвалидироваться за пределами реквеста и прочее. Для конкретных задач это может быть не проблемой, но в общем случае понижается гибкость разработки и повышается вероятность допустить ошибку.
Выйграли в бутлоаде, проиграли немного по памяти. Плюс возможность кастомизировать приложение на уровне апп сервера. У нас прирост до 40 раз.
Есть независимый синтеческий тест Ларавел от китайцев: https://www.ctolib.com/topics-132962.html
1. Почему php-cgi? Разве mod_php не быстрее?.. Мой опыт настройки серверов под битрикс показывает, что php-cgi — самый медленный вариант.
2. В коментариях увидел, что на проекте используются обученные модели, упоминание opencv и т.д. А зачем? Ну т.е. зачем нужны нейронки и библиотеки компьюетрного зрения в Вашем случае?
- php-cgi (в контексте этой статьи) — это название воркеров PHP-FPM.
- У нас нет нейронок и компьютерного зрения на PHP. Из PHP мы используем более "классические" варианты ML. Если как-то попытаться обобщить все задачи, то по сути они сводятся к тому, чтобы иметь какое-то предсказание и в зависимости от этого что-то разное пользователю показывать или предлагать.
Вот тут то, что исползуем мы: https://github.com/tony2001/xhprof/tree/badoo-7.0
Есть другие форки для PHP >=7.0 и даже в официальном репозитории есть экспериментальная ветка, но не могу сказать, насколько они хорошо работают.
Производительность PHP: планируем, профилируем, оптимизируем