Очень распространено заблуждение о том, что xslt — это сплошные тормоза, а smarty — наше всё. Отставим в сторону лаконичность синтаксиса смарти и удобство поддержки xslt, а устремим наш пристальный взор именно на скорость их работы.
Рисовать мы будем нечто чуть более сложное чем «привет мир» — дерево. Это не даст нам использовать копипасту и заставит повторно использовать код для вывода узлов. Количество их пусть будет небольшим — 100 штук.
Не сложно измерить, что составление DOM требует примерно в 3 раза больше времени. Однако, это всего-лишь предварительная обработка данных.
Результат: 1 + 20 = 21
______________________
Рисовать мы будем нечто чуть более сложное чем «привет мир» — дерево. Это не даст нам использовать копипасту и заставит повторно использовать код для вывода узлов. Количество их пусть будет небольшим — 100 штук.
Создадим простенькую объектную модель данных.
class Thing {
public $color, $shape, $childs= array();
function getArrayData(){
$childs= array();
foreach( $this->childs as $child ) $childs[]= $child->getArrayData();
$data= array(
'color' => $this->color,
'shape' => $this->shape,
'childs' => $childs,
);
return $data;
}
function getXMLData( $doc ){
$node= $doc->createElement( 'thing' );
$node->setAttribute( 'color', $this->color );
$node->setAttribute( 'shape', $this->shape );
foreach( $this->childs as $child ) $node->appendChild( $child->getXMLData( $doc ) );
return $node;
}
}
srand( 0 );
$things= array();
$colors= array( 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan' );
$shapes= array( 'circle', 'ellipse', 'oval', 'rectangle', 'triangle', 'star', 'rhombus', 'trapeze', 'exploit<u>' );
for($i=0;$i<100;++$i){
$thing= new Thing;
$thing->color= $colors[ array_rand( $colors ) ];
$thing->shape= $shapes[ array_rand( $shapes ) ];
if( $i ){
$things[ array_rand( array_slice( $things, 0, 10 ) ) ]->childs[]= $thing;
};
$things[]= $thing;
}
У каждого узла есть два метода: getArrayData возвращает поддерево в виде структуры из родных массивов, а getXMLData возвращает DOM.Не сложно измерить, что составление DOM требует примерно в 3 раза больше времени. Однако, это всего-лишь предварительная обработка данных.
XSLT преобразование
$t1= getTime();
$doc= new DOMDocument;
$data= $things[0]->getXMLData( $doc );
$t2= getTime();
$doc->appendChild( $data );
$xsl= new DOMDocument( );
$xsl->load( 'tpl.xsl' );
$proc= new XSLTProcessor( );
$proc->importStyleSheet( $xsl );
echo $proc->transformToXML( $doc );
$t3= getTime();
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match=" thing ">
<div style="color:{@color}">
<xsl:value-of select=" @color " />
<xsl:text> </xsl:text>
<xsl:value-of select=" @shape " />
</div>
<blockquote>
<xsl:apply-templates select=" thing " />
</blockquote>
</xsl:template>
</xsl:stylesheet>
Результат: 3 + 5 = 8Smarty шаблонизация
- $t1= getTime();
- $data= $things[0]->getArrayData();
- $t2= getTime();
- $smarty= new Smarty;
- $smarty->template_dir = '.';
- $smarty->compile_dir = '.';
- $smarty->assign( 'thing', $data );
- $smarty->display( 'tpl.smarty' );
- $t3= getTime();
- {function name="proc"}
- <div style="color:{$thing.color|escape}">{$thing.color|escape} {$thing.shape|escape}</div>
- <blockquote>
- {foreach from=$thing.childs item=child}
- {proc thing=$child}
- {/foreach}
- </blockquote>
- {/function}
- {proc thing=$thing}
Результат: 1 + 20 = 21
______________________
PHP быдлокод
$t1= getTime();
$data= $things[0]->getArrayData();
$t2= getTime();
include( 'tpl.php' );
$t3= getTime();
function akeurwbkurlycqvaelkuyrc( $data ){ ?>
<div style="color:<?=htmlspecialchars($data['color'])?>">
<?=htmlspecialchars($data['color'])?> <?=htmlspecialchars($data['shape'])?>
</div>
<blockquote>
<? foreach( $data['childs'] as $child ) akeurwbkurlycqvaelkuyrc( $child ) ?>
</blockquote>
<? } akeurwbkurlycqvaelkuyrc( $data );
Результат: 1 + 2 = 3Прочий код
function getTime(){
return 1000 * microtime( true );
}
<div style="position:absolute;top:0;right:0">
preprocessing: <?= $t2 - $t1 ?><br/>
templating: <?= $t3 - $t2 ?><br/>
total: <?= $t3 - $t1 ?><br/>
</div>