Skip to content

Commit

Permalink
Merge pull request #93 from koenkivits/fix/has-performance
Browse files Browse the repository at this point in the history
Improve `ServiceManager#has()` performance
  • Loading branch information
Ocramius authored Jul 24, 2021
2 parents e33e5d6 + b1ce1eb commit 8032bc5
Showing 1 changed file with 28 additions and 50 deletions.
78 changes: 28 additions & 50 deletions src/ServiceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,8 @@ public function build($name, ?array $options = null)
*/
public function has($name)
{
$strategies = $this->createServiceDetectionStrategies();
return (static function (string $name) use ($strategies): bool {
foreach ($strategies as $strategy) {
if ($strategy($name)) {
return true;
}
}

return false;
})($name);
// Check static services and factories first to speedup the most common requests.
return $this->staticServiceOrFactoryCanCreate($name) || $this->abstractFactoryCanCreate($name);
}

/**
Expand Down Expand Up @@ -952,52 +944,38 @@ private function resolveAbstractFactoryInstance($abstractFactory): void
}

/**
* @return array<int,callable>
* @psalm-return list<Closure(string):bool>
* Check if a static service or factory exists for the given name.
*/
private function createServiceDetectionStrategies(): array
private function staticServiceOrFactoryCanCreate(string $name): bool
{
$staticServiceOrFactoryCanCreate = function (string $name): bool {
return isset($this->services[$name]) || isset($this->factories[$name]);
};

$abstractFactoriesCanCreate = function (string $name): bool {
foreach ($this->abstractFactories as $abstractFactory) {
if ($abstractFactory->canCreate($this->creationContext, $name)) {
return true;
}
}

return false;
};
if (isset($this->services[$name]) || isset($this->factories[$name])) {
return true;
}

return [
// Check services and factories first to speedup the most common requests.
function (string $name) use ($staticServiceOrFactoryCanCreate): bool {
if ($staticServiceOrFactoryCanCreate($name)) {
return true;
}
$resolvedName = $this->aliases[$name] ?? $name;
if ($resolvedName !== $name) {
return $this->staticServiceOrFactoryCanCreate($resolvedName);
}

$resolvedName = $this->aliases[$name] ?? $name;
if ($resolvedName === $name) {
return false;
}
return false;
}

return $staticServiceOrFactoryCanCreate($resolvedName);
},
// Check if abstract factories can create the service
function (string $name) use ($abstractFactoriesCanCreate): bool {
if ($abstractFactoriesCanCreate($name)) {
return true;
}
/**
* Check if an abstract factory exists that can create a service for the given name.
*/
private function abstractFactoryCanCreate(string $name): bool
{
foreach ($this->abstractFactories as $abstractFactory) {
if ($abstractFactory->canCreate($this->creationContext, $name)) {
return true;
}
}

$resolvedName = $this->aliases[$name] ?? $name;
if ($resolvedName === $name) {
return false;
}
$resolvedName = $this->aliases[$name] ?? $name;
if ($resolvedName !== $name) {
return $this->abstractFactoryCanCreate($resolvedName);
}

return $abstractFactoriesCanCreate($resolvedName);
},
];
return false;
}
}

0 comments on commit 8032bc5

Please sign in to comment.