Pull to refresh

Smarty против XSLT

Reading time 5 min
Views 6.2K
Очень распространено заблуждение о том, что xslt — это сплошные тормоза, а smarty — наше всё. Отставим в сторону лаконичность синтаксиса смарти и удобство поддержки xslt, а устремим наш пристальный взор именно на скорость их работы.

Рисовать мы будем нечто чуть более сложное чем «привет мир» — дерево. Это не даст нам использовать копипасту и заставит повторно использовать код для вывода узлов. Количество их пусть будет небольшим — 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 = 8

Smarty шаблонизация

  1. $t1= getTime();
  2.         $data= $things[0]->getArrayData();
  3. $t2= getTime();
  4.         $smarty= new Smarty;
  5.         $smarty->template_dir = '.';
  6.         $smarty->compile_dir = '.';
  7.         $smarty->assign( 'thing', $data );
  8.         $smarty->display( 'tpl.smarty' );
  9. $t3= getTime();

  1. {function name="proc"}
  2. <div style="color:{$thing.color|escape}">{$thing.color|escape} {$thing.shape|escape}</div>
  3. <blockquote>
  4.         {foreach from=$thing.childs item=child}
  5.                 {proc thing=$child}
  6.         {/foreach}
  7. </blockquote>
  8. {/function}
  9. {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>


Тестовый стенд

php 5.3.1, libxml 2.7.3, libxsl 1.1.23, smarty 3 rc2

Выводы

Компиляция шаблонов в PHP вовсе не гарантирует производительности, в то время как работа с DOM не сильно и медленней нативной лапши.
Tags:
Hubs:
+6
Comments 323
Comments Comments 323

Articles