Выбирая шаблонизатор для проекта Comet, я решил сравнить все популярные в PHP-коммьюнити движки. Обычно такой выбор диктует фреймворк: симфонист шаблоны завернет в Twig, программист Laravel вооружится Blade. Но меня интересовал вопрос — как эти варианты отличаются в плане производительности? После тестирования семи движков и чистого PHP я получил ответ. Данные, графики, чемпионы и лузеры — под катом!



Имена топовых претендентов вспомнил сам, остальные нашел, вооружившись статистикой GitHub и обсуждениями на Reddit. Вот такой список получился:

Smarty: github.com/smarty-php/smarty
Plates: github.com/thephpleague/plates
Mustache: github.com/bobthecow/mustache.php
Twig: github.com/twigphp/Twig
Blade: github.com/jenssegers/blade
BladeOne: github.com/EFTEC/BladeOne
Latte: github.com/nette/latte

Если знаете интересный вариант — пишите, добавлю в тест. Blade довольно глубоко интегрирован в Laravel, поэтому пришлось взять пару его standalone-реализаций. К сожалению, ни одна из них не поддерживает компоненты Blade-X.

Чтобы понять суть бенчмарка, проще всего взглянуть на версию кода с чистым PHP:

$data = [ 
    (object) [
    "code" => 200, 
    "message" => "OK"
    ],
    (object) [
        "code" => 404, 
        "message" => "Not Found"
    ],
    (object) [
        "code" => 500, 
        "message" => "Internal Server Error"
    ],		 
];

$html = '<html><head></head><body>';
foreach ($data as $message) {
    $html .= "<p>$message->code : $message->message</p>";
}
$html .= '</body></html>';

Это синтетический тест вывода в HTML-шаблон массива из трех объектов, содержащих два свойства: HTML-код и его краткое описание.

Так выглядит аналог на Twig:

<html><head></head><body>

    {% for message in data %}
        <p>{{ message.code }} : {{ message.message }}</p>
    {% endfor %}

</body></html>

А это Blade:

<html><head></head><body>

    @foreach ($data as $message)
        <p>{{ $message->code }} : {{ $message->message }}</p>
    @endforeach

</body></html>

Тесты прогонялись в контейнере Ubuntu 20.04 / PHP 7.4 / Comet 0.6 на виртуалке с 4 ядрами Ryzen 3600 и 4G памяти:

wrk --connections=500 --threads=2 --duration=10s http://comet:8080/php

Получился такой расклад, каждый график отражает среднее количество успешно отработанных за одну секунду запросов:



Чистый PHP — ожидаемо первый, но неожиданно, что Blade отстает аж в два раза! И почему «легковесный» Plates отстает от «мощного» Twig? Все фреймворки используют штатное кеширование, так что результаты максимально приближены к реальным.

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

На правах рекламы: посмотрите на Comet, в ближайших планах — сделать его самым быстрым и удобным PHP-фреймворком для создания restful API и микросервисов :)