[DependencyInjection] perf optim: call dirname() at most 5x

This commit is contained in:
Nicolas Grekas 2014-12-04 19:27:52 +01:00
parent c11535bd6b
commit fcd8ff9b67
9 changed files with 41 additions and 11 deletions

View File

@ -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 = <<<EOF
@ -784,7 +788,7 @@ EOF;
* Constructor.
*/
public function __construct()
{
{{$targetDirs}
\$this->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 = <<<EOF
@ -823,7 +828,7 @@ EOF;
* Constructor.
*/
public function __construct()
{
{{$targetDirs}
\$this->services =
\$this->scopedServices =
\$this->scopeStacks = array();
@ -1335,16 +1340,28 @@ EOF;
}
}
private function exportTargetDirs()
{
return null === $this->targetDirRegex ? '' : <<<EOF
\$dir = __DIR__;
for (\$i = 1; \$i <= {$this->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) {

View File

@ -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);

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
class Container extends AbstractContainer
{
private $parameters;
private $targetDirs;
/**
* Constructor.

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs;
/**
* Constructor.

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs;
/**
* Constructor.

View File

@ -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].'/')));
}
/**

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs;
/**
* Constructor.

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs;
/**
* Constructor.

View File

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs;
/**
* Constructor.