О чем это я?
Ах да, я хотел вам рассказать о небольшом тесте, который я проводил на досуге. Дело в том, что я люблю изобретать велосипеды (не бейте меня ногами за это невинное хобби). Поэтому в бытность программистом-похапешником я думал над реализацией шаблонизатора (а кто не думал — пусть кинет в меня камнем).
Если вы хотите сравнения производительности известных шаблонизаторов — простите, в другой раз
Темой этой статьи является исследование производительности некоторых частных случаев использования простых шаблонов
Собственно что анализировалось
Думаю многие знаю что такое шаблоны, кто не знает читайте википедию, шаблоны это способ представления вида (View)
Собственно есть три подхода к этому делу (не считая сторонних разработок и модулей типа XML/XSLT):
- Подключение обычных PHP файлов, где описан шаблон
Чтение, парсинг и исполнение шаблона на каком-то шаблонном языке
Пункт 2 но с кэшированием скомпилированного в PHP код шаблона
Исходники тестирования
Простой инклуд
function file_included() { $vars['some'] = 'some'; include 'included.php'; }
Простой реквайр
function file_required() { $vars['some'] = 'some'; require 'included.php'; }
Чтение и исполнение файла
function file_evaled() { $vars['some'] = 'some'; $content = file_get_contents('included.php'); eval('?>'.$content); }
Парсинг регекспом
function file_tpl_preg() { $vars['some'] = 'some'; $content = file_get_contents('included.tpl'); $content = preg_replace('#\{(\w+)\}#', '<?= $vars[\'\1\'] ?>', $content); eval('?>'.$content); }
Парсинг заменой строк
function file_tpl_strtr() { $vars['some'] = 'some'; $content = file_get_contents('included.tpl'); $content = strtr($content, array( '{' => '<? $vars[\'', '}' => '\'] ?>', )); eval('?>'.$content); }
Регексп с кешированием проверкой времени изменения
function file_tpl_preg_cashe() { $file = 'included'; if (filemtime($file.'.tpl.php') < filemtime($file.'.tpl')) { $content = file_get_contents('included.tpl'); $content = preg_replace('#\{(\w+)\}#', '<?= $vars[\'\1\'] ?>', $content); file_put_contents($file.'.tpl.php', $content); } $vars['some'] = 'some'; include $file.'.tpl.php'; }
Регексп с кешированием простой проверкой существования
function file_tpl_manual_cashe() { $file = 'included'; if (!file_exists($file.'.tpl1.php')) { $content = file_get_contents('included.tpl'); $content = preg_replace('#\{(\w+)\}#', '<?= $vars[\'\1\'] ?>', $content); file_put_contents($file.'.tpl1.php', $content); } $vars['some'] = 'some'; include $file.'.tpl1.php'; }
Результаты
Вызывались функции просто в цикле, кэширование доступа к файловой системе отключено.
Тип теста
Время
% от скорейшего
file_included0.00021430100.00%
file_required0.00021500100.33%
file_evaled0.00022488104.94%
file_tpl_preg0.00024208112.96%
file_tpl_strtr0.00022802106.40%
file_tpl_preg_cashe0.00024305113.42%
file_tpl_manual_cashe0.00023100107.79%
Поясню результаты:
file_included
— простой инклуд PHP шаблона, самый быстрый
file_required
— тот же инклуд, только в профиль
file_evaled
— отдельно чтение и исполнение PHP шаблона, немного медленней
file_tpl_preg
— парсинг шаблона регекспом, на 10-12 процентов медленней инклуда
file_tpl_strtr
— парсинг с помошью быстрой замены а строках, негибкий подход, но всего на 5-6 процентов медленней
file_tpl_preg_cashe
— парсинг регекспом и кэширование с автоматической проверкой устаревания кеша. По скорости почти так же как и то же самое без кэширования, похоже filemtime очень медленная функция
file_tpl_manual_cashe
— кэширование только с проверкой существования кеша (для парсинга нужно удалить старый кеш). Довольно неплохие результаты, всего на 6-7 процентов медленней инклуда.
Выводы делайте сами :)