UPDATE: внимание - последние версии бенчмарков
здесь технологии:
как и было обещано ранее, включил последний
Smarty в
lebowski-bench. тестировалось три варианта, и во всех, разумеется, включен режим компиляции шаблона в "нативный" пхп-код. "нативный" пишу
в кавычках: кто залезал во внутрь "скомпилированного" шаблона - поймет почему, а кто не залезал - для того привожу пример в конце этого поста.
итак три варианта:
1) zps off, compile_check off
2) zps on, compile_check off
3) zps on, compile_check on
здесь zps - zend perfomance suite, а compile_check - режим, при котором smarty проверяет чек-сумму шаблона, не поменялась ли она. В случае изменений компилятор заново собирает "компилированный" шаблон.
ОЧЕНЬ ВАЖНОЕ ЗАМЕЧАНИЕ. Как и во многих других движках, реализовать bench можно по-разному: сделав "mess" кода, то есть по возможности упаковать все в один файл (самый быстрый метод, но почти непригодный для поддержки для сколь-нибудь действительно сложных проектов), и разбить код на несколько частей, отдельные методы и
шаблоны (медленнее, но удобнее, а при повторном использовании просто небходимо). Так вот, для теста смарти я выбрал первый вариант, чтобы уж точно выжать из него по максимуму, поэтому и назвал его smarty mess. То есть даем ему нефиговую такую фору, остальное будет ещё медленнее (а если взглянуть на разницу между php-mess и php-includes то можно монять, насколько медленнее). Если категоризировать прочие тесты, то к "mess"-решению относятся все тесты из приводимых, кроме php includes и
blitz.
Хочу особенно подчеркнуть, что смотреть стоит в-основном на результаты с ZPS поскольку сам код смарти весит около 140 кило, и ожидать от него каких-то нормальных результатов на в-общем совсем несложном тесте без акселератора - мягко говоря, неумно.
Итак, полные результаты, цифры - requests per second
ab -n20000 -c100, ZPS on
################################
ugly php mess: 1115
php includes: 754
blitz t-cache: 746
blitz: 683
smarty-mess(2): 628
php_templates: 617
smarty-mess(3): 584
ab -n20000 -c100, ZPS off
################################
ugly php mess: 662
php_templates: 449
blitz t-cache: 443
blitz: 427
php includes: 285
smarty-mess(1): 125
машина
PC PIV 2,8GHz (HT off) 1GB; linux-2.6.8, php-4.3.10 (Apache/1.3.33
static), zps (output cache off)
blitz (0.3), php_templates(1.7): so-модули, -O2
smarty: 2.6.10, tpl-compile on, output-cache off
Напоследок, два примера. В бенче есть "полосатый" список разделов, с небольшой дополнительной логикой:
если у элемента списка есть спец-атрибут, при выводе название дополняется небольшим куском кода.
Методом php-mess это записывается в следующем виде:
$n_sections
=
count
(
$_DATA
[
'SECTIONS'
]);
for(
$i
=
0
;
$i
<
$n_sections
;
$i
++) {
$sdata
= &
$_DATA
[
'SECTIONS'
][
$i
];
?>
echo (
$i
%
2
) ?
'eeeeee'
:
'dddddd'
;
?>>
[
0
];
?>">
[
1
];
?>
if(
$sdata
[
2
]) {
?>R.I.P.
}
?>
}
?>
на языке Smarty запись этого дела будет чуть поудобнее:
{section name=i loop=$sections}
{$sections[i].1}
{if $sections[i].2 }R.I.P.{/if}
{/section}
А вот "откомпилированный" шаблон. Что называется, почувствуйте разницу.
unset($this->_sections['i']);
$this->_sections['i']['name'] = 'i';
$this->_sections['i']['loop'] = is_array($_loop=$this->_tpl_vars['sections']) ? count($_loop) : max(0, (int)$_loop); unset(
$_loop);
$this->_sections['i']['show'] = true;
$this->_sections['i']['max'] = $this->_sections['i']['loop'];
$this->_sections['i']['step'] = 1;
$this->_sections['i']['start'] = $this->_sections['i']['step'] > 0 ? 0 : $this->_sections['i']['loop']-1;
if ($this->_sections['i']['show']) {
$this->_sections['i']['total'] = $this->_sections['i']['loop'];
if ($this->_sections['i']['total'] == 0)
$this->_sections['i']['show'] = false;
} else
$this->_sections['i']['total'] = 0;
if ($this->_sections['i']['show']):
for ($this->_sections['i']['index'] = $this->_sections['i']['start'], $this->_sections['i']['iteration'] = 1;
$this->_sections['i']['iteration'] <= $this->_sections['i']['total'];
$this->_sections['i']['index'] += $this->_sections['i']['step'], $this->_sections['i']['iteration']++):
$this->_sections['i']['rownum'] = $this->_sections['i']['iteration'];
$this->_sections['i']['index_prev'] = $this->_sections['i']['index'] - $this->_sections['i']['step'];
$this->_sections['i']['index_next'] = $this->_sections['i']['index'] + $this->_sections['i']['step'];
$this->_sections['i']['first'] = ($this->_sections['i']['iteration'] == 1);
$this->_sections['i']['last'] = ($this->_sections['i']['iteration'] == $this->_sections['i']['total']);
?>
if ((1 & $this->_sections['i']['index'])): ?>#eeeeeeelse: ?>#ddddddendif; ?>>
echo $this->_tpl_vars['sections'][$this->_sections['i']['index']]['0']; ?>
">echo $this->_tpl_vars['sections'][$this->_sections['i']['index']]['1']; ?>
if ($this->_tpl_vars['sections'][$this->_sections['i']['index']]['2']): ?>R.I.P.hp endif; ?>
endfor; endif; ?>
Ниже приводится полный код теста, вдруг вы предлодите более оптимальный вариант ;)
скрипт:
include_once('../data.inc');
require('/usr/local/lib/php/Smarty/Smarty.class.php');
$tpl = new Smarty();
$tpl->template_dir = './';
$tpl->compile_dir = './t_cache';
$tpl->compile_check = true;
//$tpl->compile_check = false;
// root vars
$tpl->assign(
array (
'num_total' => $_STAT['TOTAL'],
'num_online'=> count($_STAT['ONLINE']),
'poll_title' => $_POLL['TITLE'],
'poll_question' => $_POLL['QUESTION'],
'poll_button' => $_POLL['BUTTON'],
)
);
// adverts
shuffle($_ADVERTS);
$tpl->assign_by_ref('adverts',$_ADVERTS);
// sections
$tpl->assign_by_ref('sections',$_SECTIONS);
// users
$tpl->assign_by_ref('users',$_STAT['ONLINE']);
// news
$tpl->assign_by_ref('news',$_NEWS);
// poll
$tpl->assign_by_ref('poll_answers',$_POLL['ANSWERS']);
// out
$tpl->display('main.tpl');
?>
шаблон:
BlitzExample
{section name=i loop=$adverts max=3}
{$adverts[i].0}
{$adverts[i].1} {/section}
{section name=i loop=$sections}
{$sections[i].1}{if $sections[i].2 }R.I.P.{/if}
{/section}
Users: {$num_total}
Online: {$num_online}
{foreach from=$users item=i}
{$i.1}{/foreach}
{$poll_title}
{$poll_question}
{foreach item=i from=$news}
{$i.0} {$i.2}
{$i.3}
[ read full story ] {/foreach}
BlitzExample (Copyleft) Alexey A. Rybak, 2005.
Texts are taken from IMDB.com, Memorable Quotes from "The Big Lebowski" (Ethan & Joel Coen, 1998).
You are welcome to send any suggestions or comments to raa@phpclub.net