Skip to content

Commit

Permalink
Merge pull request #36 from koriym/singleton
Browse files Browse the repository at this point in the history
Performance boost by removing $isSingleton meta file access in runtime
  • Loading branch information
koriym authored Mar 5, 2018
2 parents c8c2231 + db5cb8c commit 99f8274
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 23 deletions.
35 changes: 29 additions & 6 deletions src/DependencyCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt;
use Ray\Di\Container;
use Ray\Di\Dependency;
use Ray\Di\DependencyInterface;
Expand Down Expand Up @@ -102,14 +101,37 @@ public function setQaulifier(IpQualifier $qualifer) : void
$this->qualifier = $qualifer;
}

/**
* Return "return [$node, $isSingleton]" node
*/
public function getReturnCode(Expr $instance, bool $isSingleton) : Node\Stmt\Return_
{
$bool = $isSingleton ? 'true' : 'false';
$singletonInt = new Expr\ConstFetch(new Node\Name([$bool]));
$return = new Node\Stmt\Return_(
new Node\Expr\Array_(
[
new Expr\ArrayItem(
$instance
),
new Expr\ArrayItem(
$singletonInt
)
]
)
);

return $return;
}

/**
* Compile DependencyInstance
*/
private function compileInstance(Instance $instance) : Code
{
$node = $this->normalizer->__invoke($instance->value);

return new Code(new Node\Stmt\Return_($node), false);
return new Code($this->getReturnCode($node, false));
}

/**
Expand All @@ -120,9 +142,9 @@ private function compileDependency(Dependency $dependency) : Code
$prop = $this->privateProperty;
$node = $this->getFactoryNode($dependency);
$this->aopCode->__invoke($dependency, $node);
$node[] = new Node\Stmt\Return_(new Node\Expr\Variable('instance'));
$node = $this->factory->namespace('Ray\Di\Compiler')->addStmts($node)->getNode();
$isSingleton = $prop($dependency, 'isSingleton');
$node[] = $this->getReturnCode(new Node\Expr\Variable('instance'), $isSingleton);
$node = $this->factory->namespace('Ray\Di\Compiler')->addStmts($node)->getNode();
$qualifer = $this->qualifier;
$this->qualifier = null;

Expand All @@ -141,9 +163,10 @@ private function compileDependencyProvider(DependencyProvider $provider) : Code
if ($this->context) {
$node[] = $this->getSetContextCode($this->context); // $instance->setContext($this->context);
}
$node[] = new Stmt\Return_(new MethodCall(new Expr\Variable('instance'), 'get'));
$node = $this->factory->namespace('Ray\Di\Compiler')->addStmts($node)->getNode();
$isSingleton = $prop($provider, 'isSingleton');
$methodCall = new MethodCall(new Expr\Variable('instance'), 'get');
$node[] = $this->getReturnCode($methodCall, $isSingleton);
$node = $this->factory->namespace('Ray\Di\Compiler')->addStmts($node)->getNode();
$qualifer = $this->qualifier;
$this->qualifier = null;

Expand Down
17 changes: 8 additions & 9 deletions src/ScriptInjector.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,16 @@ public function __construct($scriptDir)
$this->registerLoader();
$prototype = function ($dependencyIndex, array $injectionPoint = []) {
$this->ip = $injectionPoint;
list($instance) = $this->getScriptInstance($dependencyIndex);

return $this->getScriptInstance($dependencyIndex);
return $instance;
};
$singleton = function ($dependencyIndex, array $injectionPoint = []) {
if (isset(self::$singletons[$this->injectorId][$dependencyIndex])) {
return self::$singletons[$this->injectorId][$dependencyIndex];
}
$this->ip = $injectionPoint;
$instance = $this->getScriptInstance($dependencyIndex);
list($instance) = $this->getScriptInstance($dependencyIndex);
self::$singletons[$this->injectorId][$dependencyIndex] = $instance;

return $instance;
Expand All @@ -93,8 +94,8 @@ public function getInstance($interface, $name = Name::ANY)
if (isset(self::$singletons[$this->injectorId][$dependencyIndex])) {
return self::$singletons[$this->injectorId][$dependencyIndex];
}
$instance = $this->getScriptInstance($dependencyIndex);
if ($this->isSingleton($dependencyIndex) === true) {
list($instance, $isSingleton) = $this->getScriptInstance($dependencyIndex);
if ($isSingleton) {
self::$singletons[$this->injectorId][$dependencyIndex] = $instance;
}

Expand Down Expand Up @@ -126,19 +127,17 @@ public function unserialize($serialized)
}

/**
* @return mixed
* @return array [$instance, $isSingleton]
*/
private function getScriptInstance(string $dependencyIndex)
private function getScriptInstance(string $dependencyIndex) : array
{
$file = \sprintf(DependencySaver::INSTANCE_FILE, $this->scriptDir, \str_replace('\\', '_', $dependencyIndex));
if (! \file_exists($file)) {
return $this->onDemandCompile($dependencyIndex);
}
list($prototype, $singleton, $injection_point, $injector) = $this->functions;

$instance = require $file;

return $instance;
return require $file;
}

/**
Expand Down
16 changes: 8 additions & 8 deletions tests/DependencyCompilerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function testInstanceCompileString()
$expected = <<<'EOT'
<?php
return 'bear';
return array('bear', false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand All @@ -44,7 +44,7 @@ public function testInstanceCompileInt()
$expected = <<<'EOT'
<?php
return 1;
return array(1, false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand All @@ -56,7 +56,7 @@ public function testInstanceCompileArray()
$expected = <<<'EOT'
<?php
return array(1, 2, 3);
return array(array(1, 2, 3), false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand All @@ -78,7 +78,7 @@ public function testDependencyCompile()
$instance->setSpareMirror($singleton('Ray\\Compiler\\FakeMirrorInterface-right'));
$instance->setHandle($prototype('Ray\\Compiler\\FakeHandleInterface-{ANY}', array('Ray\\Compiler\\FakeCar', 'setHandle', 'handle')));
$instance->postConstruct();
return $instance;
return array($instance, false);
EOT;
$expected = \str_replace('{ANY}', Name::ANY, $expectedTemplate);
$this->assertSame($expected, (string) $code);
Expand All @@ -95,7 +95,7 @@ public function testDependencyProviderCompile()
namespace Ray\Di\Compiler;
$instance = new \Ray\Compiler\FakeHandleProvider('momo');
return $instance->get();
return array($instance->get(), false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand All @@ -108,7 +108,7 @@ public function testDependencyInstanceCompile()
$expected = <<<'EOT'
<?php
return 'momo';
return array('momo', false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand All @@ -121,7 +121,7 @@ public function testDependencyObjectInstanceCompile()
$expected = <<<'EOT'
<?php
return unserialize('O:23:"Ray\\Compiler\\FakeEngine":0:{}');
return array(unserialize('O:23:"Ray\\Compiler\\FakeEngine":0:{}'), false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand All @@ -144,7 +144,7 @@ public function testContextualProviderCompile()
$instance = new \Ray\Compiler\FakeContextualProvider();
$instance->setContext('context');
return $instance->get();
return array($instance->get(), false);
EOT;
$this->assertSame($expected, (string) $code);
}
Expand Down

0 comments on commit 99f8274

Please sign in to comment.