К сожалению, мне неизвестна ни одна простая, универсальная и по-настоящему корректная методика анализа производительности шаблонных движков. А результатами любых искусственных, или как их ещё принято называть, синтетических, тестов пользоваться нужно максимально осторожно. Тем не менее, здесь приводятся результаты двух тестов. Первый тест — классический, измеряющий скорость выполнения циклических итераций одного и того же шаблона. Тест крайне простой, но позволяющий достаточно условно разделить группы движков на «нормальные», «медленные» и «никуда не годные». Число итераций и переменных в блоке было взято по умолчанию (9 переменных, 50 итераций), результаты этого теста приведены в таблице 1. Как легко видеть, Blitz, по крайней мере, аутсайдером не является.
Таблица 2.1. Классический тест производительности
Тестовая машина (A): сервер XEON*2 2,4GHz (HT on) 2GB; linux php-4.3.10(fgci) zps nginx blitz, php_templates: so-модули, CFLAGS: -g3 -O2 | |||
---|---|---|---|
№ | Engine name | Time | Percentage |
1 | php | 0.000544 | 100% |
2 | blitz | 0.001008 | 185% |
3 | php_templates | 0.001812 | 333% |
4 | smarty | 0.002006 | 369% |
5 | str_replace | 0.003713 | 683% |
6 | phemplate | 0.004514 | 830% |
7 | fasttemplate | 0.006835 | 1256% |
8 | vtemplate | 0.009565 | 1758% |
9 | ultratemplate | 0.012993 | 2388% |
10 | templatepower | 0.017056 | 3135% |
11 | bugitemplate | 0.019989 | 3674% |
12 | phplib | 0.028053 | 5157% |
13 | profTemplate | 0.043104 | 7924% |
14 | xtemplate | 0.048799 | 8970% |
Тестовая машина (B): PC PIV 2,8GHz (HT off) 1GB; linux-2.6.8 php-4.3.10 (Apache/1.3.33 static) zps blitz, php_templates: so-модули, CFLAGS -g -O2 | |||
---|---|---|---|
№ | Engine name | Time | Percentage |
1 | php | 0.00045 | 100% |
2 | blitz | 0.000834 | 185% |
3 | php_templates | 0.001595 | 354% |
4 | smarty | 0.001694 | 376% |
5 | str_replace | 0.00373 | 829% |
6 | phemplate | 0.004215 | 937% |
7 | fasttemplate | 0.006139 | 1364% |
8 | vtemplate | 0.008755 | 1946% |
9 | ultratemplate | 0.012747 | 2833% |
10 | templatepower | 0.018678 | 4151% |
11 | bugitemplate | 0.019286 | 4286% |
12 | phplib | 0.025478 | 5662% |
13 | profTemplate | 0.045148 | 10033% |
14 | xtemplate | 0.048137 | 10697% |
Столь сильное отличие php от прочих движков объясняется тем, что весь код php-теста упакован в один файл, в то время для остальных есть два файла — php-файл контроллера и шаблонный файл, который парсится котроллером.
В результаты этого теста не включены некоторые известные шаблонные движки, такие как madtemplate, PEAR::Sigma и PEAR::HTML_Template_IT по простой причине: они не были установлены на тестовых машинах. Однако, насколько мне известно, эти проекты не являются кандидатами на попадание в пятерку лидеров. В этом можно убедиться, например, проведя онлайн-тесты самостоятельно, или скачав тестирующую программу.
Второй тест более приближен к полевым условиям. Он представляет собой тестирование некоторой динамической страницы, подготовленной с использованием разных движков, при помощи стандартной утилиты ab. Итак, у нас есть страница какого-то псевдопортала, содержащая:
ротирующиеся рекламные уши (3 шт.);
«полосатую» навигацию (~10 разделов);
горячие новости (~10 шт.);
список пользователи онлайн (~20 шт.);
голосовалка с вариантами ответов (3 ответа);
прочие переменные на странице (~5 шт).
Для тестирования было выбрано 4 подхода:
ugly php mess: используется только php, причем весь код полностью упакован в один файл, представляя собой эдакую «кашу». Такой прием практически никогда не встречается в реальных больших проектах, но включен в тесты исключительно ради интереса, поскольку очевидно является самым быстрым.
php includes: используется только php, функционально разные блоки (элементы списков) вынесены в отдельные файлы.
php_templates: один шаблон, на каждый функциональный блок — контекст.
blitz includes: разные шаблоны на каждый функциональный блок, подключаемые через include
.
blitz ctx: один шаблон, на каждый функциональный блок — контекст.
blitz ctx arrays: один шаблон, на каждый функциональный блок — контекст, один вызов установки массива итераций.
blitzpack: разные шаблоны на каждый функциональный блок, упакованые в один blitzpack, подключаемые через include
.
smarty: один шаблон, на функциональные блоки — циклы внутри шаблона.
Все данные упакованы в структуру в отдельном файле, который инклюдится во всех тестовых вариантах. Числа запросов в секунду, которое выполняет сервер для каждого из методов, представлены в таблице 2.
Таблица 2.2. Тест производительности приближенный к полевым условиям
Тестовая машина(B), см. таблицу 1 | |
---|---|
ab -n20000 -c100, ZPS on | |
ugly php mess | 1150 |
blitz ctx arrays | 890 |
blitz ctx | 825 |
php includes | 770 |
blitzpack | 725 |
blitz incudes | 680 |
smarty | 620 |
php_templates | 615 |
Тестовая машина(B), см. таблицу 1 | |
---|---|
ab -n20000 -c100, ZPS off | |
ugly php mess | 660 |
blitz ctx arrays | 590 |
blitz ctx | 560 |
php_templates | 450 |
blitzpack | 440 |
blitz incudes | 430 |
smarty | 285 |
php includes | 125 |
К сожалению, я не имел возможности провести тесты для других шаблонных движков (впрочем, код для этого теста доступен, вы можете добавить в него решения исходной задачи с использованием любых других средств). Поэтому ограничусь обобщенной интерпретацией этих результатов. То, что native PHP-код вместе с акселератором всегда будут быстрее прочих решений — очевидно. Правда, следует особенно подчеркнуть, что native в этом смысле — именно написанный программистом самим, а не «скомпилированный». В этом легко убедиться, заглянув внутрь любого «скомпилированного» шаблона: как правило, их код состоит из многомерных, довольно сложных для выполнения конструкций, значительно сложнее, чем написанный правильными руками код ;) Поскольку разница между blitz и «правильным» методом php includes не является кардинальной, а все синтетические тесты позволяют лишь выявить группы приблизительно равных, можно с определенной долей уверенности считать методы разработки с использованием php, blitz и php_templates примерно одинаковыми по производительности.
Следует также принять во внимание, что в реальном проекте разница в скорости между различными методами, скорее всего, будет ещё меньше. Во-первых, это связано с тем, что значительное время будет тратиться на работу с источниками данных (СУБД, различные сервисы и проч.). Во-вторых, отношение «количества» кода, относящегося к уровню представления, и прочего кода будет совершенно иным. Грубо говоря, view_code = full_code для тестов и пусть выигрыш на синтетическом тесте составляет даже десятки процентов. Но в реальном проекте часто выполняется соотношение view_code >> full_code, и поэтому выигрыш на уровне представления уже почти ничего не даст. Как вы могли заметить, почти все тесты были проведены с использованием акселератора из ZPS. Вряд ли сейчас можно представить крупный проект, в котором не используется акселератор, однако, акселератор акселератору рознь. И вполне возможно вы получите совершенно иные результаты при использовании, например, eAccelerator'a. В-общем, призываю вас не полагаться полностью на приведенные результаты. Скачивайте тесты, экспериментируйте на реальных задачах, и выбирайте те решения, которые дают выигрыш в вашем проекте.