feature #2641 Optimize performance of calls to extensions at runtime (fabpot)

This PR was squashed before being merged into the 2.x branch (closes #2641).

Discussion
----------

Optimize performance of calls to extensions at runtime

Commits
-------

540c9006 updated CHANGELOG
f4c5152f optimized calls to custom extension runtimes
279993b2 optimized performance when accessing extensions in templates
This commit is contained in:
Fabien Potencier
2018-03-02 12:54:10 -08:00
9 changed files with 25 additions and 8 deletions
+1
View File
@@ -1,5 +1,6 @@
* 2.4.5 (2017-XX-XX)
* optimized the performance of calling an extension method at runtime
* optimized the performance of the dot operator for array and method calls
* added an exception when using "===" instead of "same as"
* fixed possible array to string conversion concealing actual error
+1 -1
View File
@@ -46,7 +46,7 @@ class Twig_Node_CheckSecurity extends Twig_Node
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("try {\n")
->indent()
->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n")
->write("\$this->extensions['Twig_Extension_Sandbox']->checkSecurity(\n")
->indent()
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
+7 -1
View File
@@ -28,7 +28,13 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
}
} elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
// For BC/FC with namespaced aliases
$class = (new ReflectionClass(get_class($callable[0])))->name;
if (!$compiler->getEnvironment()->hasExtension($class)) {
throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $class));
}
$compiler->raw(sprintf('$this->extensions[\'%s\']->%s', ltrim($class, '\\'), $callable[1]));
} else {
$closingParenthesis = true;
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', ucfirst($this->getAttribute('type')), $this->getAttribute('name')));
+1 -1
View File
@@ -25,7 +25,7 @@ class Twig_Node_Sandbox extends Twig_Node
{
$compiler
->addDebugInfo($this)
->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n")
->write("\$sandbox = \$this->extensions['Twig_Extension_Sandbox'];\n")
->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n")
->indent()
->write("\$sandbox->enableSandbox();\n")
+1 -1
View File
@@ -25,7 +25,7 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
{
$compiler
->addDebugInfo($this)
->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(')
->write('echo $this->extensions[\'Twig_Extension_Sandbox\']->ensureToStringAllowed(')
->subcompile($this->getNode('expr'))
->raw(");\n")
;
+2 -2
View File
@@ -24,9 +24,9 @@ class Twig_Profiler_Node_EnterProfile extends Twig_Node
public function compile(Twig_Compiler $compiler)
{
$compiler
->write(sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name')))
->write(sprintf('$%s = $this->extensions[', $this->getAttribute('var_name')))
->repr($this->getAttribute('extension_name'))
->raw(");\n")
->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(', ')
+10
View File
@@ -38,9 +38,19 @@ abstract class Twig_Template
protected $blocks = array();
protected $traits = array();
/**
* @internal
*/
protected $extensions = array();
public function __construct(Twig_Environment $env)
{
$this->env = $env;
foreach ($env->getExtensions() as $extension) {
// For BC/FC with namespaced aliases
$class = (new ReflectionClass(get_class($extension)))->name;
$this->extensions[ltrim($class, '\\')] = $extension;
}
}
/**
+1 -1
View File
@@ -28,7 +28,7 @@ class Twig_Tests_Node_SandboxTest extends Twig_Test_NodeTestCase
$tests[] = array($node, <<<EOF
// line 1
\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');
\$sandbox = \$this->extensions['Twig_Extension_Sandbox'];
if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {
\$sandbox->enableSandbox();
}
+1 -1
View File
@@ -24,7 +24,7 @@ class Twig_Tests_Node_SandboxedPrintTest extends Twig_Test_NodeTestCase
$tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 1), 1), <<<EOF
// line 1
echo \$this->env->getExtension('Twig_Extension_Sandbox')->ensureToStringAllowed("foo");
echo \$this->extensions['Twig_Extension_Sandbox']->ensureToStringAllowed("foo");
EOF
);