Friday, October 9. 2009eZ Components Template is not slow...
... you may just not have used it appropriately. Fabien Potencier has blogged about templating engines, compared their speed and finally concluded that his own templating engine is the fastest. Not only that, but my beloved eZ Components Template engine, which we use with great pleasure at YMC, came out as the slowest in his benchmark. (Althought he complimented it as "probably the one which have the most features".)
Dear Fabien, I think it's not fair to blog a benchmark without publishing the code you used to do the benchmark! But even without the code and without doing my own benchmark, I can offer some explanations, why eZ Components may have been the slowest in your benchmark and why you've compared apples with oranges. I take the compiled template code from the Twig site: CODE: /* Hello {{ name }} */
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
{
public function display($context)
{
$this->env->initRuntime();
// line 1
echo "Hello ";
echo (isset($context['name']) ? $context['name'] : null);
}
} Thinks to keep in mind from the Twig compiled template:
CODE: {use $name}
{use $items}
Hello {$name}
{foreach $items as $item}
* {$item}
{/foreach}
And the resulting code: CODE: <?php
// Generated PHP file from template code.
// If you modify this file your changes will be lost when it is regenerated.
$this->checkRequirements(1,array("disableCache" => false));
$i_output = "";
if ( !isset($this->send->name))
{
throw new ezcTemplateRuntimeException( sprintf("The external (use) variable '%s' is not set in template: %s and called from %s",
'name',
$this->template->stream,
( sizeof($this->template->streamStack) >= 2
? $this->template->streamStack[sizeof($this->template->streamStack) - 2] : 'the application code') ) );
}
if ( !isset($this->send->items))
{
throw new ezcTemplateRuntimeException( sprintf("The external (use) variable '%s' is not set in template: %s and called from %s",
'items',
$this->template->stream,
( sizeof($this->template->streamStack) >= 2
? $this->template->streamStack[sizeof($this->template->streamStack) - 2] : 'the application code') ) );
}
$i_output .= " \nHello ";
$i_output .= htmlspecialchars($this->send->name);
$i_output .= "\n \n";
foreach ($this->send->items as $t_item)
{
$i_output .= "* ";
$i_output .= htmlspecialchars($t_item);
$i_output .= "\n";
}
return $i_output;
?> The differences are:
So in conclusion: Please post the benchmark code, so that we can debug it and please compare the template engines with the same features turned on or off! Comments
The code has been since published on my blog:
http://fabien.potencier.org/benchmark.tgz. As you will see for yourself, the Twig templates also have output escaping enabled for the benchmark, and so the call to htmlspecialchars() is there too. As for performance is concerned, I have talked with several people at eZ about the issue and they are investigating the problem. And I don't really care that much about Twig being the fastest. But frankly, the performance of the eZ component is just intriguing to say the least.
An interesting explanation, indeed.
Could you test using a decorator to the template code generator whose generated code does not contain the calls to verify presence of variables and see if there is ant noticeable speed/memory gain? After all if the variables where there at compile time, I think they should be there at runtime too, possibly NULL, but not disappear. Is this wrong? Usage of echo + ob_start might also be worth investigating, instead of storing the template result into variables that are presumably copied a few times over before being outputted... Last but not least, could you explain in more detail the advantages of using members of an object to store template vars instead of a plain array? I have the feeling that some nice improvements might come as a result of this discussion...
How each engine rewrites the code and caches it is beside the point. Comparing that is like comparing how two class interfaces work - what happens behind the scenes is up to the person providing the interface, not the person using it.
What happens when you do $user->Get($username); is not your concern, you're just using the interface provided. While it's good to understand how each one works, you shouldn't need to do that to use a particular tool.
Thomas, seen my issue on eZBase::autoload()?
ref: http://issues.ez.no/IssueView.php?Id=15666&activeItem=2 From what I have seen, close to 80% of the performance difference can be explained by this very speed bump. The rest is mix of maturity and something we can fix during a days work of profiling.. MVCTools, while being one of the fastest MVC implementation already, also gets a similar huge speed boost by not using the autloader. So a simplistic autoloader like Twig (direct Class name to path mapping) or eZ Publish (pre cached class to path array) would really benefit eZ Components performance wise. |
Tracked: Oct 14, 18:35
Tracked: Oct 14, 18:59