From fcd8ff9b67fd63159e5e37dd529de38ff73d6431 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 4 Dec 2014 19:27:52 +0100 Subject: [PATCH] [DependencyInjection] perf optim: call dirname() at most 5x --- .../DependencyInjection/Dumper/PhpDumper.php | 33 ++++++++++++++----- .../Tests/Dumper/PhpDumperTest.php | 3 +- .../Tests/Fixtures/php/services1-1.php | 1 + .../Tests/Fixtures/php/services1.php | 1 + .../Tests/Fixtures/php/services10.php | 1 + .../Tests/Fixtures/php/services12.php | 10 ++++-- .../Tests/Fixtures/php/services8.php | 1 + .../Tests/Fixtures/php/services9.php | 1 + .../Tests/Fixtures/php/services9_compiled.php | 1 + 9 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 58b34e39e9..0c7ac26cb8 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -104,17 +104,19 @@ class PhpDumper extends Dumper ), $options); if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) { - // Build a regexp where the first two root dirs are mandatory, + // Build a regexp where the first root dirs are mandatory, // but every other sub-dir is optional up to the full path in $dir + // Mandate at least 2 root dirs and not more that 5 optional dirs. $dir = explode(DIRECTORY_SEPARATOR, realpath($dir)); $i = count($dir); if (3 <= $i) { $regex = ''; - $this->targetDirMaxMatches = $i - 3; + $lastOptionalDir = $i > 8 ? $i - 5 : 3; + $this->targetDirMaxMatches = $i - $lastOptionalDir; - while (2 < --$i) { + while (--$i >= $lastOptionalDir) { $regex = sprintf('(%s%s)?', preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); } @@ -765,6 +767,7 @@ $bagClass class $class extends $baseClass { private \$parameters; + private \$targetDirs; EOF; } @@ -777,6 +780,7 @@ EOF; private function addConstructor() { $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + $targetDirs = $this->exportTargetDirs(); $code = <<parameters = $parameters; parent::__construct(new ParameterBag(\$this->parameters)); @@ -816,6 +820,7 @@ EOF; private function addFrozenConstructor() { $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + $targetDirs = $this->exportTargetDirs(); $code = <<services = \$this->scopedServices = \$this->scopeStacks = array(); @@ -1335,16 +1340,28 @@ EOF; } } + private function exportTargetDirs() + { + return null === $this->targetDirRegex ? '' : <<targetDirMaxMatches}; ++\$i) { + \$this->targetDirs[\$i] = \$dir = dirname(\$dir); + } +EOF; + } + private function export($value) { if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { $prefix = $matches[0][1] ? var_export(substr($value, 0, $matches[0][1]), true).'.' : ''; $suffix = $matches[0][1] + strlen($matches[0][0]); $suffix = isset($value[$suffix]) ? '.'.var_export(substr($value, $suffix), true) : ''; - $dirname = '__DIR__'; - for ($i = $this->targetDirMaxMatches - count($matches); 0 <= $i; --$i) { - $dirname = sprintf('dirname(%s)', $dirname); + if (0 < $dirname = 1 + $this->targetDirMaxMatches - count($matches)) { + $dirname = sprintf('$this->targetDirs[%d]', $dirname); + } else { + $dirname = '__DIR__'; } if ($prefix || $suffix) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 4eca6aa849..e240376fd2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -70,13 +70,14 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase $definition = new Definition(); $definition->setClass('stdClass'); $definition->addArgument('%foo%'); - $definition->addArgument(array('%foo%' => '%foo%')); + $definition->addArgument(array('%foo%' => '%buz%/')); $container = new ContainerBuilder(); $container->setDefinition('test', $definition); $container->setParameter('foo', 'wiz'.dirname(dirname(__FILE__))); $container->setParameter('bar', dirname(__FILE__)); $container->setParameter('baz', '%bar%/PhpDumperTest.php'); + $container->setParameter('buz', dirname(dirname(__DIR__))); $container->compile(); $dumper = new PhpDumper($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php index 560da91642..2834baef42 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class Container extends AbstractContainer { private $parameters; + private $targetDirs; /** * Constructor. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php index 23d367f1f9..aa4e70f51e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs; /** * Constructor. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php index bf64894f58..55196f882a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services10.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs; /** * Constructor. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php index 1829818dbc..f38d7d9eaa 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php @@ -17,19 +17,25 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs; /** * Constructor. */ public function __construct() { + $dir = __DIR__; + for ($i = 1; $i <= 5; ++$i) { + $this->targetDirs[$i] = $dir = dirname($dir); + } $this->services = $this->scopedServices = $this->scopeStacks = array(); $this->parameters = array( - 'foo' => ('wiz'.dirname(__DIR__)), + 'foo' => ('wiz'.$this->targetDirs[1]), 'bar' => __DIR__, 'baz' => (__DIR__.'/PhpDumperTest.php'), + 'buz' => $this->targetDirs[2], ); $this->set('service_container', $this); @@ -53,7 +59,7 @@ class ProjectServiceContainer extends Container */ protected function getTestService() { - return $this->services['test'] = new \stdClass(('wiz'.dirname(__DIR__)), array(('wiz'.dirname(__DIR__)) => ('wiz'.dirname(__DIR__)))); + return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), array(('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/'))); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php index a6de38e381..558c284e8b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services8.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs; /** * Constructor. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 90b5476776..c993d96ec7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs; /** * Constructor. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 97fe3ad8a0..12a0653c48 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; class ProjectServiceContainer extends Container { private $parameters; + private $targetDirs; /** * Constructor.