-
-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize the check for inlined services #2339
Conversation
} | ||
|
||
// Only cache the remove service IDs in debug mode | ||
$removedIds = $container->getParameter('kernel.debug') ? (static::$removedServiceIds ?: $container->getRemovedIds()) : $container->getRemovedIds(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any debugging benefit from not caching the service IDs in debug mode for the current request?
It seems that you are never setting |
Good catch! 😆 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the current logic a little confusing:
if (\is_object($strClass)) {
// Use object
}
elseif (isset(static::$arrSingletons[$strClass])) {
// Use object
}
elseif ($container->has($strClass) && (strpos($strClass, '\\') !== false || !class_exists($strClass))) {
// Get service
}
elseif (($container->getParameter('kernel.debug') || !class_exists($strClass)) && self::isServiceInlined($strClass)) {
// throw ServiceNotFoundException()
}
elseif (!class_exists($strClass)) {
// throw RuntimeException('class not found')
}
Why don't we make the "class not found" case more straight-forward?
if (\is_object($strClass)) {
// Use object
}
elseif (isset(static::$arrSingletons[$strClass])) {
// Use object
}
elseif ($container->has($strClass) && (strpos($strClass, '\\') !== false || !class_exists($strClass))) {
// Get service
}
elseif (!class_exists($strClass)) {
if (self::isServiceInlined($strClass)) {
// throw ServiceNotFoundException()
}
// throw RuntimeException('class not found')
}
This would not consider the case when a class exists but the service was inlined. If I define a service for a class, I would always assume the service is used. That's why we currently check for that case first, but for performance reasons this PR changes it to only check in dev mode. |
It apparently does more than that, because the prior condition was |
Our current implementation calls
$container->getRemovedIds()
for every class before checking if its a singleton. This results in a lot of overhead, because$container->getRemovedIds()
loads the removed IDs from file on every access. I assume that's to not memory-cache the IDs, but in our case it results in a ton of unnecessary calls.The behavior of
System::import()
andSystem::importStatic()
have slightly changed:In debug mode, the existing behavior will remain the same. In production, we use
getInstance()
or try to create a new instance of the class before checking for removed IDs.