While looking at ClassLoader.php stuff I noticed class load misses for views_page_display_pre_render. That didn't make any sense because its a function not a class so why would something be testing if it is a class?
Turns out #2247779: Allow #pre_render, #post_render and #post_render_cache callbacks to be service methods adds code in \Drupal\Core\Render\Renderer::doRender()
to resolve services defined in pre-render and there is a little bit of a performance bug in \Drupal\Core\Controller\ControllerResolver::getControllerFromDefinition()
.
if (strpos($controller, ':') === FALSE) {
if (method_exists($controller, '__invoke')) {
return new $controller;
}
elseif (function_exists($controller)) {
return $controller;
}
}
This code checks if the method exists on the controller class first which means we go through the entire fairly expensive process of trying to autoload class before checking if the function exists. When we are resolving a function this means we _always_ hit the worst possible path in that code which is really really slow.
By swapping this, if the controller was a class implementing magic methods we'll hit the additional function_exists() before resolving it but these seems like a fair trade for missing the autoload look up on functions.
Comment | File | Size | Author |
---|---|---|---|
controllerResolver-performance.patch | 810 bytes | neclimdul | |
Comments
Comment #1
neclimdulAlso, props to timplunkett for pointing me to the issue and the problem that caused this. At least half the credit of tracking this down goes to him.
Comment #2
neclimdulComment #3
dawehnerFair
Comment #4
alexpottBased on #1 I added tim.plunkett to the commit message. This issue is a normal bug fix, and doesn't include any disruptive changes, so it is allowed per https://www.drupal.org/core/beta-changes. Committed 2b6baf6 and pushed to 8.0.x. Thanks!
Comment #6
Wim LeersGreat catch!