Add benchmark

This commit is contained in:
Ivan Shalganov 2013-01-25 19:13:33 +04:00
parent 164ab85594
commit 4f42efbb9a
16 changed files with 5274 additions and 180 deletions

26
benchmark/run.php Normal file
View File

@ -0,0 +1,26 @@
<?php
echo "Smarty3 vs Twig vs Aspect\n\n";
echo "Generate templates... ";
passthru("php ".__DIR__."/templates/inheritance/smarty.gen.php");
passthru("php ".__DIR__."/templates/inheritance/twig.gen.php");
echo "Done\n";
echo "Testing large output...\n";
passthru("php ".__DIR__."/templates/echo.php");
echo "\nTesting 'foreach' of big array...\n";
passthru("php ".__DIR__."/templates/foreach.php");
echo "\nTesting deep 'inheritance'...\n";
passthru("php ".__DIR__."/templates/inheritance.php");
echo "\nDone. Cleanup.\n";
passthru("rm -rf ".__DIR__."/compile/*");
passthru("rm -f ".__DIR__."/templates/inheritance/smarty/*");
passthru("rm -f ".__DIR__."/templates/inheritance/twig/*");
echo "\nSmarty3 vs Aspect (more details)\n\n";
echo "Coming soon\n";

View File

@ -0,0 +1,50 @@
<?php
$data = json_decode(file_get_contents(__DIR__.'/echo/data.json'), true);
exec("rm -rf ".__DIR__."/../compile/*");
require(__DIR__.'/../../vendor/autoload.php');
$smarty = new Smarty();
$smarty->compile_check = false;
$smarty->setTemplateDir(__DIR__);
$smarty->setCompileDir(__DIR__."/../compile/");
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('echo/smarty.tpl');
var_dump("Smarty3: ".(microtime(true)-$start));
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('echo/smarty.tpl');
var_dump("Smarty3 cached: ".(microtime(true)-$start));
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem(__DIR__);
$twig = new Twig_Environment($loader, array(
'cache' => __DIR__."/../compile/",
'autoescape' => false,
'auto_reload' => false,
));
$start = microtime(true);
$template = $twig->loadTemplate('echo/twig.tpl');
$template->render($data);
var_dump("Twig: ".(microtime(true)-$start));
$start = microtime(true);
$template = $twig->loadTemplate('echo/twig.tpl');
$template->render($data);
var_dump("Twig cached: ".(microtime(true)-$start));
$aspect = Aspect::factory(__DIR__, __DIR__."/../compile/", Aspect::CHECK_MTIME);
$start = microtime(true);
$template = $aspect->fetch('echo/smarty.tpl', $data);
var_dump("Aspect: ".(microtime(true)-$start));
$start = microtime(true);
$template = $aspect->fetch('echo/smarty.tpl', $data);
var_dump("Aspect cached: ".(microtime(true)-$start));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
<?php
$data = json_decode(file_get_contents(__DIR__.'/foreach/data.json'), true);
exec("rm -rf ".__DIR__."/../compile/*");
require(__DIR__.'/../../vendor/autoload.php');
$smarty = new Smarty();
$smarty->compile_check = false;
$smarty->setTemplateDir(__DIR__);
$smarty->setCompileDir(__DIR__."/../compile/");
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('foreach/smarty.tpl');
var_dump("Smarty3: ".(microtime(true)-$start));
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('foreach/smarty.tpl');
var_dump("Smarty3 cached: ".(microtime(true)-$start));
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem(__DIR__);
$twig = new Twig_Environment($loader, array(
'cache' => __DIR__."/../compile/",
'autoescape' => false,
'auto_reload' => false,
));
$start = microtime(true);
$template = $twig->loadTemplate('foreach/twig.tpl');
$template->render($data);
var_dump("Twig: ".(microtime(true)-$start));
$start = microtime(true);
$template = $twig->loadTemplate('foreach/twig.tpl');
$template->render($data);
var_dump("Twig cached: ".(microtime(true)-$start));
$aspect = Aspect::factory(__DIR__, __DIR__."/../compile/", Aspect::CHECK_MTIME | Aspect::INCLUDE_SOURCES);
$start = microtime(true);
$template = $aspect->fetch('foreach/smarty.tpl', $data);
var_dump("Aspect: ".(microtime(true)-$start));
$start = microtime(true);
$template = $aspect->fetch('foreach/smarty.tpl', $data);
var_dump("Aspect cached: ".(microtime(true)-$start));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<h1>Вывод 10 полей из 1000 элементов в цикле<h1>
{foreach $array as $item}
{$item.id} {$item.title} {$item.var1} {$item.var2} {$item.var3} {$item.var4} {$item.var5} {$item.var6} {$item.var5} {$item.var6}
{/foreach}

View File

@ -0,0 +1,4 @@
<h1>Вывод 10 полей из 1000 элементов в цикле<h1>
{% for item in array %}
{{ item.id }} {{ item.title }} {{ item.var1 }} {{ item.var2 }} {{ item.var3 }} {{ item.var4 }} {{ item.var5 }} {{ item.var6 }} {{ item.var5 }} {{ item.var6 }}
{% endfor %}

View File

@ -0,0 +1,61 @@
<?php
$data = array(
"inh" => 'inheritance',
"var1" => 'val1'
);
function trace() {
$e = new Exception();
echo $e->getTraceAsString();
ob_flush();
exit(0);
}
exec("rm -rf ".__DIR__."/../compile/*");
require(__DIR__.'/../../vendor/autoload.php');
$smarty = new Smarty();
$smarty->compile_check = false;
$smarty->setTemplateDir(__DIR__);
$smarty->setCompileDir(__DIR__."/../compile/");
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('inheritance/smarty/b100.tpl');
var_dump("Smarty3: ".(microtime(true)-$start));
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('inheritance/smarty/b100.tpl');
var_dump("Smarty3 cached: ".(microtime(true)-$start));
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem(__DIR__);
$twig = new Twig_Environment($loader, array(
'cache' => __DIR__."/../compile/",
'autoescape' => false,
'auto_reload' => false,
));
$start = microtime(true);
$template = $twig->loadTemplate('inheritance/twig/b100.tpl');
$template->render($data);
var_dump("Twig: ".(microtime(true)-$start));
$start = microtime(true);
$template = $twig->loadTemplate('inheritance/twig/b100.tpl');
$template->render($data);
var_dump("Twig cached: ".(microtime(true)-$start));
$aspect = Aspect::factory(__DIR__, __DIR__."/../compile/", Aspect::CHECK_MTIME);
$start = microtime(true);
$template = $aspect->fetch('inheritance/smarty/b100.tpl', $data);
var_dump("Aspect: ".(microtime(true)-$start));
$start = microtime(true);
$template = $aspect->fetch('inheritance/smarty/b100.tpl', $data);
var_dump("Aspect cached: ".(microtime(true)-$start));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
<?php
$b0 = '<h1>Вывод статических данных в 500 наследуемых блоков</h1>' . "\r\n";
for($i = 1; $i < 501; $i++)
{
$b0 .= '{block b'.$i.'}{/block}'."\r\n";
$data = '{extends "inheritance/smarty/b'.($i-1).'.tpl"}' . "\r\n";
$data .= '{block b'.$i.'}data'.$i.'{/block}' . "\r\n";
file_put_contents(__DIR__.'/smarty/b'.$i.'.tpl', $data);
}
file_put_contents(__DIR__.'/smarty/b0.tpl', $b0);

View File

@ -0,0 +1,10 @@
<?php
$b0 = '<h1>Вывод статических данных в 500 наследуемых блоков</h1>' . "\r\n";
for($i = 1; $i < 501; $i++)
{
$b0 .= '{% block b'.$i.' %}{% endblock %}'."\r\n";
$data = '{% extends "inheritance/twig/b'.($i-1).'.tpl" %}' . "\r\n";
$data .= '{% block b'.$i.' %}data'.$i.'{% endblock %}' . "\r\n";
file_put_contents(__DIR__.'/twig/b'.$i.'.tpl', $data);
}
file_put_contents(__DIR__.'/twig/b0.tpl', $b0);

View File

@ -2,7 +2,7 @@
"name": "megagroup/aspect",
"type": "library",
"description": "Aspect - faster templater for PHP",
"keywords": ["aspect", "templater", "templating"],
"keywords": ["aspect", "templater", "templating", "yohoho"],
"license": "MIT",
"authors": [
{
@ -15,7 +15,9 @@
"ext-tokenizer": "*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
"phpunit/phpunit": "3.7.*",
"smarty/smarty": "3.*",
"twig/twig": "1.*"
},
"autoload": {
"psr-0": { "Aspect": "src/" }

View File

@ -24,32 +24,6 @@ class Tokenizer {
const WHITESPACE = 2;
const LINE = 3;
/**
* Strip whitespace tokens (default)
*/
const DECODE_TEXT = 0;
/**
* Strip whitespace tokens, exclude newlines
*/
const DECODE_NEW_LINES = 1;
/**
* Allow all whitespace tokens
*/
const DECODE_WHITESPACES = 2;
/**
* Decode mask
*/
const DECODE = 3;
/**
* Strip duplicate whitespaces. For example \n\n => \n
*/
const FILTER_DUP_WHITESPACES = 128;
/**
* Filter mask
*/
const FILTERS = 4080;
/**
* Some text value: foo, bar, new, class ...
*/
@ -157,14 +131,12 @@ class Tokenizer {
*
* @static
* @param string $query
* @param int $options one of DECODE_*, FILTER_* constants
* @return array
*/
public static function decode($query, $options = 0) {
public static function decode($query) {
$tokens = array(-1 => array(\T_WHITESPACE, '', '', 1));
$_tokens = token_get_all("<?php ".$query);
$line = 1;
$decode = $options & self::DECODE;
array_shift($_tokens);
$i = 0;
foreach($_tokens as &$token) {
@ -177,36 +149,7 @@ class Tokenizer {
);
$i++;
} elseif ($token[0] === \T_WHITESPACE) {
if(!$decode) {
$tokens[$i-1][2] = $token[1];
} elseif($decode == 1) {
if(strpos($token[1], "\n") !== false) {
$frags = explode("\n", $token[1]);
$ws = array_shift($frags);
if($ws) {
$tokens[$i-1][2] .= $ws;
}
foreach($frags as $frag) {
$tokens[] = array(
\T_WHITESPACE,
"\n",
$frag,
$line = $token[2],
);
$i++;
}
} else {
$tokens[$i-1][2] .= $token[1];
}
} else {
$tokens[] = array(
$token[0],
$token[1],
"",
$line = $token[2],
);
$i++;
}
$tokens[$i-1][2] = $token[1];
} else {
$tokens[] = array(
$token[0],
@ -219,19 +162,6 @@ class Tokenizer {
}
if($options & self::FILTER_DUP_WHITESPACES) {
$prev = null;
foreach($tokens as &$token) {
if($token[0] === T_WHITESPACE && $prev && $prev[0] === T_WHITESPACE) {
$prev = false;
}
$prev = &$token;
}
$tokens = array_values(array_filter($tokens));
}
return $tokens;
}

View File

@ -46,112 +46,6 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase {
$this->assertSame("+", $tokens->getNext($tokens::MACRO_BINARY));
}
public function testWhitespaceSenseLow() {
$text = "1 foo \n bar\n \n double ";
$tokens = new Tokenizer($text, Tokenizer::DECODE_NEW_LINES);
$this->assertTrue($tokens->valid());
$this->assertSame("1", $tokens->current());
$this->assertSame(T_LNUMBER, $tokens->key());
$this->assertSame(" ", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("foo", $tokens->current());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame(" ", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("\n", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame(" ", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("bar", $tokens->current());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("\n", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame(" ", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("\n", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame(" ", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("double", $tokens->current());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame(" ", $tokens->getWhiteSpace());
$tokens->next();
$this->assertFalse($tokens->valid());
$this->assertNull($tokens->key());
}
public function testWhitespaceSenseHi() {
$text = "1 foo \n bar\n \n double ";
$tokens = new Tokenizer($text, Tokenizer::DECODE_WHITESPACES);
$this->assertTrue($tokens->valid());
$this->assertSame("1", $tokens->current());
$this->assertSame(T_LNUMBER, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame(" ", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("foo", $tokens->current());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame(" \n ", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("bar", $tokens->current());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("\n \n ", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame("double", $tokens->current());
$this->assertSame(T_STRING, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertTrue($tokens->valid());
$this->assertSame(" ", $tokens->current());
$this->assertSame(T_WHITESPACE, $tokens->key());
$this->assertSame("", $tokens->getWhiteSpace());
$tokens->next();
$this->assertFalse($tokens->valid());
$this->assertNull($tokens->key());
}
public function testSkip() {
$text = "1 foo: bar ( 3 + double ) ";
$tokens = new Tokenizer($text);