Pull to refresh

Smarty vs. Twig: производительность

Website development *PHP *
Smarty — один из самых старых шаблонизаторов для PHP. Если вы программируете на PHP — скорее всего, вам приходилось работать с ним. В 2010 году вышла третья версия этого шаблонизатора. Smarty 3 был написан с чистого листа, с активным использованием PHP5. Вместе с этим Smarty получил обновлённый синтаксис и современные возможности, включая наследование, песочницу и др.
Twig — молодой шаблонизатор от разработчиков Symfony. Авторы позиционируют его как быстрый и функциональный шаблонизатор. По возможностям он во многом похож на Smarty 3. Twig отличает несколько другой синтаксис, а так же заявленная высокая производительность. Проверим?

Тестирование


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

Код для Smarty получился очень простым:
$data = json_decode(file_get_contents('data.json'), true);
require('smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->compile_check = false;
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('demo.tpl');
echo microtime(true)-$start;

Для Twig несколько сложнее:
$data = json_decode(file_get_contents('data.json'), true);
require('twig/Autoloader.php');
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('templates');
$twig = new Twig_Environment($loader, array(
	'cache' => 'templates_c',
	'autoescape' => false,
	'auto_reload' => false,
));
$start = microtime(true);
$template = $twig->loadTemplate('demo.tpl');
$template->render($data);
echo microtime(true)-$start;

Оба шаблонизатора настроены похожим образом: выключено автоматическое экранирование, отключена автоматическая перекомпиляция шаблонов при изменениях.

Получение значений переменных


Получение значений переменных — наиболее активно используемая операция. В сложных шаблонах она может использоваться по нескольку сотен раз. Поначалу может показаться, что скорость выполнения этой операции не должна зависеть от шаблонизатора, однако это не так. Для хранения шаблонных переменных должна использоваться какая-то структура. Чем она проще — тем быстрее работает получение значений переменных. Для оценки производительности этой операции сгенерируем шаблон, в котором будет просто выводиться значение 10000 переменных и ничего более.

Smarty:
{$var0} {$var1} {$var2} {$var3} {$var4} ...

Twig:
{{ var0 }} {{ var1 }} {{ var2 }} {{ var3 }} {{ var4 }} ...

Результат:
Компиляция Выполнение
Smarty 3.1.1 16.320 сек. 0.058 сек.
Twig 1.2.0 9.757 сек. 0.083 сек.
В таблице приведены средние значения из нескольких последовательных тестов. Как видно, десять тысяч синтаксических конструкций очень долго компилировалось обоими участниками теста. Smarty в этом плане сильно отстал от Twig. Однако, компиляция выполняется всего один раз, а в дальнейшем работает уже скомпилированная версия шаблона, поэтому время работы последнего намного важнее. И здесь уже Smarty уверенно на ≈30% быстрее оппонента.

Обход массивов и вывод значений полей


Ни один более-менее серьёзный шаблон не обходится без foreach. Для теста напишем шаблон, который выводит по 10 полей из 1000 элементов массива.

Smarty:
{foreach $array as $item}
{$item.id} {$item.title} {$item.var1} {$item.var2} {$item.var3} {$item.var4} {$item.var5} {$item.var6} {$item.var5} {$item.var6} 
{/foreach}

Twig:
{% for item in array %}
{{ item.id }} {{ item.title }} {{ item.var1 }} {{ item.var2 }} {{ item.var3 }} {{ item.var4 }} {{ item.var5 }} {{ item.var6 }} {{ item.var5 }} {{ item.var6 }} 
{% endfor %}

Результат:
Компиляция Выполнение
Smarty 3.1.1 0.065 сек. 0.009 сек.
Twig 1.2.0 0.131 сек. 0.082 сек.
Здесь происходит нечто невероятное: скомпилированный шаблон Smarty выполняется почти в 10 раз быстрее, чем вариант Twig! Более того, даже компиляция+выполнение в Smarty работает быстрее выполнения готового скомпилированного шаблона в Twig. Из этого можно сделать вывод, что компилятор шаблонов Smarty инициализируется быстрее Twig, но судя по предыдущему тесту работает медленнее, что на маленьких шаблонах практически незаметно.

Наследование


Наследование шаблонов — это очень удобный механизм. Только из-за этого можно полюбить тестируемые шаблонизаторы :) Давайте узнаем, какие накладные расходы появляются при использовании наследования в Smarty и Twig. Для этого создадим один родительский шаблон с 500 блоками, и ещё 500 маленьких шаблонов, каждый из которых будет наследоваться друг от друга, заполняя статическими данными один из 500 блоков родительского шаблона. Шаблонизатору отдадим на растерзание последнего в цепочке.

Результат:
Компиляция Выполнение
Smarty 3.1.1 1.329 сек. 0.002 сек.
Twig 1.2.0 2.641 сек. 0.121 сек.
Smarty отработал в 60 раз быстрее. Если взглянуть на скомпилированный код, то легко понять, что это не предел. Smarty объединил всю цепочку из наследуемых шаблонов в один большой файл, будто изначально и не было никакого наследования. То есть в результате при использовании наследования вообще нет потерь производительности! Twig же старательно создал для каждого шаблона по красивому классу и файлу, и при каждой генерации страницы загружает всё это добро.

Итого


Вывод напрашивается сам собой: Smarty быстрее Twig. Компиляция больших шаблонов занимает больше времени, но в результате мы получаем лучшую производительность.
Для тестирования использовался ноутбук. Pentium Dual-Core T4200 (2 GHz), 3GB RAM — ничего сверхъестественного. Использованная версия PHP — 5.3. На случай, если у вас появится желание самостоятельно оценить производительность Smarty и Twig на вашем оборудовании, вы можете скачать исходные коды всех тестов одним архивом.
Tags:
Hubs:
Total votes 102: ↑86 and ↓16 +70
Views 31K
Comments 170
Comments Comments 170

Posts