PHP подкаст #14

Скачать mp3 (55Мб)

Краткая серия статей (перевод от Mail.ru Group) об оптимизациях в PHP7 от Джульена Паули. Blackfire взят в качестве профилировщика. Первое, о чем стоит упомянуть — это оптимизированные массивы. Избегая ассоциативных массивов в угоду обычным — где индексом является число -, а также сортируя ключи массива по возрастанию можно достичь существенного (до 10 раз) повышения производительности. Другая приятная особенность — экономия памяти, которую многие уже заметили. Дело в том, что в 7 версии переиспользуются контейнеры переменных. Единожды выделенная память для переменной может быть повторно использована. Также улучшена работа с encapsed-строками (строки в двойных кавычках/Heredoc): вместо последовательного довыделения буфера происходит его единовременная аллокация. Также существенно улучшена работа со статическими массивами. Теперь интерпретатор различает изменяемые и неизменяемые/immutable массивы (часть OPCache расширения), поэтому сейчас можно не переживать по поводу разных map-массивов. Также существенно улучшена работа со ссылками. В ранних версиях преобразование переменной в ссылку приводило к полному копированию содержимого переменной, поэтому оптимизации как в C/C++ не получалось. В новой версии дополнительных аллокаций памяти не случается в случае преобразования не ссылочной переменной в ссылку. Для погружения в детали лучше прочесть статью от Никиты Попова.

В преддверии выхода Laravel 5.4 Тейлор Отвел поделился бенчмарком от blackfire. Hello world приложение с одним дефолтным маршрутом: 8мс, 1.8Мб RAM, 622 rps (mean).

У Laravel (5.3) Collections появился метод partition, который позволяет быстро разбить массив по некоторому признаку. Работа с коллекциями через collect в Laravel организована удобно: код становится значительно более читаемым, если вы используете map/reduce/другие методы, вместо array_map/array_reduce.

Примечательная статья об использовании Transient паттерна. Вся история вокруг Money типа, который захотелось сделать immutable. Незадача в том, что менеджерский абстрактный класс часто создает “ненужные” временные объекты типа Money. Это повышает требования к RAM. Автором был предложен паттерн Transient, который налагает на разработчика заботу о разделении режима mutable/immutable в сущностном классе. Хотите добавить несколько долларов к существующему объекту типа Money? Не проблема: вместо создания промежуточных объектов, мы можем мутировать текущий, но в определенном mutable-контексте, задаваемом единственным вспомогательным методом (вынесен в trait) withMutable(callable $fn). Функция $fn вызывается в mutable-контексте, задаваемом флагом mutable. Из недостатков — нужно переместить логику из абстрактного класса, который менеджерит манипуляцию immutable сущностями в сами сущности и писать по два обработчика: на случай mutable == true и mutable == false. Мутабельность становится контролируемой и в итоге все равно возвращает immutable объекты при снижении промежуточного инстанцирования. Читать далее PHP подкаст #14

PHP подкаст #13

Command паттерн, HAL для API, Varnish и Си спешит на помощь.

Скачать mp3 (27Мб)

Command паттерн используется для абстрагирования от технических деталей в пользу бизнес логики. Команду можно формировать из HTTP запроса, введенных данных в CLI и т.д. Команда содержит все необходимые данные для её обработки. Command Bus паттерн также способствует упрощению кода путем инкапсуляции:

  • Бизнес-логика перемещается в специальные хэндлеры и становится независимой от фреймворка (разлепляемся с реквестом, например).
  • Тонкий контроллер.
  • Упрощается тестирование.
  • Меньше дублирования кода.
  • Пространство для маневра за счет middleware (Decoration / Chain of responsibility).
  • Восстановление состояния системы за счет выполнения залогированных ранее команд.

Использование Command Bus особенно удобно в присутствии Service Layer, что предполагает скорее крупное приложение, чем небольшое. Часто — но не обязательно — мы говорим о Command Bus в контексте CQRS. Другим преимуществом Command Bus является разделение вызова и обработчика, что способствует последующему масштабированию — обработчик команды можно вынести за периметр приложения. Этот паттерн в некотором смысле также гарантирует перетекание ненужных зависимостей от фреймворка в бизнес-логику.

Реализаций командных шин предостаточно. Самые популярные:

Команда (Command) — это как правило объект с публичным атрибутами, своеобразный DTO. Здесь гармонично смотрятся get/set-методы. В командный объект целесообразно, например, мэпить реквест посредством форм-компонента или путем десериализации. Читать далее PHP подкаст #13