forked from twigphp/Twig
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature twigphp#1597 added a profiler (fabpot)
This PR was merged into the 1.17-dev branch. Discussion ---------- added a profiler This profiler allows to better understand what's going on when rendering templates. It should be used when debug is true only as it adds some overhead. Here is a sample output in the text format: ``` main 567.04ms/100% └ index 463.28ms/82% └ base 463.24ms/82% └ base::block(header) └ index::block(content) 306.29ms/54% │ └ included 50.18ms/9% │ └ included 45.42ms/8% │ └ included 35.42ms/6% │ └ base::block(content) 104.97ms/19% │ │ └ included 34.90ms/6% │ └ included 35.84ms/6% └ base::block(footer) 156.84ms/28% └ included 38.96ms/7% └ base::macro(foo) ``` You can also dump a profile in a Blackfire compatible format to [visualise the data as a graph](http://goo.gl/RwNGFH). A profile is also a great way to be able to list all templates/blocks/macros that were used when rendering a template. A PR on Symfony (symfony/symfony#13428) integrates this profiler in the Symfony web profiler to replace the current TimedTwigEngine and to add a new Twig panel.  Commits ------- 4408caa added a profiler
- Loading branch information
Showing
19 changed files
with
816 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,7 @@ | |
}, | ||
"extra": { | ||
"branch-alias": { | ||
"dev-master": "1.17-dev" | ||
"dev-master": "1.18-dev" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Twig. | ||
* | ||
* (c) 2015 Fabien Potencier | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
class Twig_Extension_Profiler extends Twig_Extension | ||
{ | ||
private $actives; | ||
|
||
public function __construct(Twig_Profiler_Profile $profile) | ||
{ | ||
$this->actives = array($profile); | ||
} | ||
|
||
public function enter(Twig_Profiler_Profile $profile) | ||
{ | ||
$this->actives[0]->addProfile($profile); | ||
array_unshift($this->actives, $profile); | ||
} | ||
|
||
public function leave(Twig_Profiler_Profile $profile) | ||
{ | ||
$profile->leave(); | ||
array_shift($this->actives); | ||
|
||
if (1 === count($this->actives)) { | ||
$this->actives[0]->leave(); | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getNodeVisitors() | ||
{ | ||
return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName())); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return 'profiler'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Twig. | ||
* | ||
* (c) 2015 Fabien Potencier | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/** | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
class Twig_Profiler_Dumper_Blackfire | ||
{ | ||
public function dump(Twig_Profiler_Profile $profile) | ||
{ | ||
$data = array(); | ||
$this->dumpProfile('main()', $profile, $data); | ||
$this->dumpChildren('main()', $profile, $data); | ||
|
||
$start = microtime(true); | ||
$str = <<<EOF | ||
file-format: BlackfireProbe | ||
cost-dimensions: wt mu pmu | ||
request-start: {$start} | ||
EOF; | ||
|
||
foreach ($data as $name => $values) { | ||
$str .= "{$name}//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n"; | ||
} | ||
|
||
return $str; | ||
} | ||
|
||
private function dumpChildren($parent, Twig_Profiler_Profile $profile, &$data) | ||
{ | ||
foreach ($profile as $p) { | ||
if ($p->isTemplate()) { | ||
$name = $p->getTemplate(); | ||
} else { | ||
$name = sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName()); | ||
} | ||
$this->dumpProfile(sprintf('%s==>%s', $parent, $name), $p, $data); | ||
$this->dumpChildren($name, $p, $data); | ||
} | ||
} | ||
|
||
private function dumpProfile($edge, Twig_Profiler_Profile $profile, &$data) | ||
{ | ||
if (isset($data[$edge])) { | ||
$data[$edge]['ct'] += 1; | ||
$data[$edge]['wt'] += floor($profile->getDuration() * 1000000); | ||
$data[$edge]['mu'] += $profile->getMemoryUsage(); | ||
$data[$edge]['pmu'] += $profile->getPeakMemoryUsage(); | ||
} else { | ||
$data[$edge] = array( | ||
'ct' => 1, | ||
'wt' => floor($profile->getDuration() * 1000000), | ||
'mu' => $profile->getMemoryUsage(), | ||
'pmu' => $profile->getPeakMemoryUsage(), | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Twig. | ||
* | ||
* (c) 2015 Fabien Potencier | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/** | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text | ||
{ | ||
static private $colors = array( | ||
'block' => '#dfd', | ||
'macro' => '#ddf', | ||
'template' => '#ffd', | ||
'big' => '#d44', | ||
); | ||
|
||
public function dump(Twig_Profiler_Profile $profile) | ||
{ | ||
return '<pre>'.parent::dump($profile).'</pre>'; | ||
} | ||
|
||
protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix) | ||
{ | ||
return sprintf('%s└ <span style="background-color: %s">%s</span>', $prefix, self::$colors['template'], $profile->getTemplate()); | ||
} | ||
|
||
protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix) | ||
{ | ||
return sprintf('%s└ %s::%s(<span style="background-color: %s">%s</span>)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName()); | ||
} | ||
|
||
protected function formatTime(Twig_Profiler_Profile $profile, $percent) | ||
{ | ||
return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Twig. | ||
* | ||
* (c) 2015 Fabien Potencier | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/** | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
class Twig_Profiler_Dumper_Text | ||
{ | ||
private $root; | ||
|
||
public function dump(Twig_Profiler_Profile $profile) | ||
{ | ||
return $this->dumpProfile($profile); | ||
} | ||
|
||
protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix) | ||
{ | ||
return sprintf('%s└ %s', $prefix, $profile->getTemplate()); | ||
} | ||
|
||
protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix) | ||
{ | ||
return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName()); | ||
} | ||
|
||
protected function formatTime(Twig_Profiler_Profile $profile, $percent) | ||
{ | ||
return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent); | ||
} | ||
|
||
private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false) | ||
{ | ||
if ($profile->isRoot()) { | ||
$this->root = $profile->getDuration(); | ||
$start = $profile->getName(); | ||
} else { | ||
if ($profile->isTemplate()) { | ||
$start = $this->formatTemplate($profile, $prefix); | ||
} else { | ||
$start = $this->formatNonTemplate($profile, $prefix); | ||
} | ||
$prefix .= $sibling ? '│ ' : ' '; | ||
} | ||
|
||
$percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0; | ||
|
||
if ($profile->getDuration() * 1000 < 1) { | ||
$str = $start."\n"; | ||
} else { | ||
$str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent)); | ||
} | ||
|
||
$nCount = count($profile->getProfiles()); | ||
foreach ($profile as $i => $p) { | ||
$str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount); | ||
} | ||
|
||
return $str; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Twig. | ||
* | ||
* (c) 2015 Fabien Potencier | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/** | ||
* Represents a profile enter node. | ||
* | ||
* @author Fabien Potencier <[email protected]> | ||
*/ | ||
class Twig_Profiler_Node_EnterProfile extends Twig_Node | ||
{ | ||
public function __construct($extensionName, $type, $name, $varName) | ||
{ | ||
parent::__construct(array(), array('extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName)); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function compile(Twig_Compiler $compiler) | ||
{ | ||
$compiler | ||
->write(sprintf("\$%s = \$this->env->getExtension(", $this->getAttribute('var_name'))) | ||
->repr($this->getAttribute('extension_name')) | ||
->raw(");\n") | ||
->write(sprintf("\$%s->enter(\$%s = new Twig_Profiler_Profile(\$this->getTemplateName(), ", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) | ||
->repr($this->getAttribute('type')) | ||
->raw(", ") | ||
->repr($this->getAttribute('name')) | ||
->raw("));\n\n") | ||
; | ||
} | ||
} |
Oops, something went wrong.