Speed up adding extensions to an environment

This commit is contained in:
Nicolas Grekas
2026-09-24 18:47:14 +02:00
parent efa368c8d7
commit d3d13f9b1a
3 changed files with 48 additions and 9 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.30.0 (2026-XX-XX)
* Speed up adding extensions to an environment
* Fix the escaping safe analysis retaining every compiled template node for the lifetime of the environment
* Speed up loading a template that the environment has already loaded
* Speed up rendering by compiling a cheaper generator guard into templates
+9 -9
View File
@@ -169,7 +169,7 @@ class Environment
public function enableDebug()
{
$this->debug = true;
$this->updateOptionsHash();
$this->optionsHash = null;
}
/**
@@ -180,7 +180,7 @@ class Environment
public function disableDebug()
{
$this->debug = false;
$this->updateOptionsHash();
$this->optionsHash = null;
}
/**
@@ -231,7 +231,7 @@ class Environment
public function enableStrictVariables()
{
$this->strictVariables = true;
$this->updateOptionsHash();
$this->optionsHash = null;
}
/**
@@ -242,7 +242,7 @@ class Environment
public function disableStrictVariables()
{
$this->strictVariables = false;
$this->updateOptionsHash();
$this->optionsHash = null;
}
/**
@@ -324,7 +324,7 @@ class Environment
*/
public function getTemplateClass(string $name, ?int $index = null): string
{
$key = ($this->hotCache[$name] ?? $this->getLoader()->getCacheKey($name)).$this->optionsHash;
$key = ($this->hotCache[$name] ?? $this->getLoader()->getCacheKey($name)).($this->optionsHash ??= $this->getOptionsHash());
return '__TwigTemplate_'.hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $key).(null === $index ? '' : '___'.$index);
}
@@ -701,7 +701,7 @@ class Environment
public function addExtension(ExtensionInterface $extension)
{
$this->extensionSet->addExtension($extension);
$this->updateOptionsHash();
$this->optionsHash = null;
}
/**
@@ -712,7 +712,7 @@ class Environment
public function setExtensions(array $extensions)
{
$this->extensionSet->setExtensions($extensions);
$this->updateOptionsHash();
$this->optionsHash = null;
}
/**
@@ -952,9 +952,9 @@ class Environment
return $this->extensionSet->getExpressionParsers();
}
private function updateOptionsHash(): void
private function getOptionsHash(): string
{
$this->optionsHash = implode(':', [
return implode(':', [
$this->extensionSet->getSignature(),
\PHP_MAJOR_VERSION,
\PHP_MINOR_VERSION,
+38
View File
@@ -655,6 +655,44 @@ EOF
FilesystemHelper::removeDir($dir);
}
}
public function testTemplateClassFollowsExtensionsAddedAfterItWasComputed(): void
{
$twig = new Environment(new ArrayLoader(['index' => '']));
$cls = $twig->getTemplateClass('index');
$twig->addExtension(new EnvironmentTest_Extension_WithGlobals());
$this->assertNotSame($cls, $cls = $twig->getTemplateClass('index'));
$twig->setExtensions([new EnvironmentTest_ExtensionWithoutRuntime()]);
$this->assertNotSame($cls, $cls = $twig->getTemplateClass('index'));
$other = new Environment(new ArrayLoader(['index' => '']));
$other->setExtensions([new EnvironmentTest_Extension_WithGlobals(), new EnvironmentTest_ExtensionWithoutRuntime()]);
$this->assertSame($cls, $other->getTemplateClass('index'));
}
public function testTemplateClassFollowsDebugAndStrictVariablesChanges(): void
{
$twig = new Environment(new ArrayLoader(['index' => '']));
$cls = $twig->getTemplateClass('index');
$twig->enableDebug();
$debugCls = $twig->getTemplateClass('index');
$this->assertNotSame($cls, $debugCls);
$this->assertSame((new Environment(new ArrayLoader(['index' => '']), ['debug' => true]))->getTemplateClass('index'), $debugCls);
$twig->disableDebug();
$this->assertSame($cls, $twig->getTemplateClass('index'));
$twig->enableStrictVariables();
$strictCls = $twig->getTemplateClass('index');
$this->assertNotSame($cls, $strictCls);
$this->assertSame((new Environment(new ArrayLoader(['index' => '']), ['strict_variables' => true]))->getTemplateClass('index'), $strictCls);
$twig->disableStrictVariables();
$this->assertSame($cls, $twig->getTemplateClass('index'));
}
}
class EnvironmentTest_Extension_WithGlobals extends AbstractExtension