AnnotatedClassDiscovery::getDefinitions takes 8-17 s (!!!) when viewing 50 nodes with up to 4 comments.
XHProf Link:
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run=51f3790f24ac9&s...
Steps to reproduce
* Install Drupal 8
* drush -y dl devel
* drush -y en devel devel_generate
* Generate 50 nodes with up to 4 comments
* Change the front-page view to show:
** 50 nodes
** Change the row mode plugin to show comments (tick the checkbox)
* Load the frontpage and wait, wait, wait ...
Steps to measure
* Install xhprof-kit (https://github.com/LionsAd/xhprof-kit)
* Goto /index-perf.php
* Follow the xhprof-link at the bottom of the page
* Find the function and look yourself.
Proposed resolution
@todo
Comments
Comment #1
dawehnerThis shows all kind of actual different kind of bugs.
Comment #2
fabianx commented#1 fixes the performance problem and it is only taking 2s instead of 10s before and Annotations taking 8s before:
XHProf-Run: http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run=51f3c0cd6b1da&s...
=> I don't know what this is doing and why it is necessary (hence can't RTBC it), but it fixes the performance bug.
XHProf-Diff:
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run2=51f3c0cd6b1da&...
Comment #3
dawehnerThe reason why this works is the following code in the plugin manager:
So instead of asking the discovery for every plugin definition, it builds them once and reuses it.
Comment #4
fabianx commentedThis makes sense to me, tests still pass => RTBC
A quick grep for discovery->getDefinition() shows:
I am not sure if the factories need to use the discovery, but I trust dawehner having done the right thing above. (hence leaving RTBC)
Comment #5
tim.plunkettIn the Factory classes, using $this->discovery is correct
And the test ones are fine as is.
+1 for RTBC
Comment #6
Anonymous (not verified) commentedso, we're happy with Yet Another Static Cache one step removed from whatever cache invalidation mechanism is in place for discovery?
i get it's only within a single request, but perhaps we should push it down a level?
Comment #7
tim.plunkettWe're not adding any of that here. Just not bypassing it by calling into a deeper object.
Comment #8
berdirYes, this changed by using the default plugin manager that does caching itself and not as part of the discovery decorator chain.
Fix is correct and is something we need to check for upcoming conversions.
Comment #9
alexpottNice find Fabianx!
Committed 8242143 and pushed to 8.x. Thanks!
Comment #10
catchIt's not good that there's two ways to get exactly the same information, one of which should never be used. Could we discuss making it harder to make this mistake?
Also looking at the xhprof we still have menu local tasks taking 20ms, I followed up on #2046565: Cache the local action plugins that appear per route.
Comment #11
dawehnerThe reason why this was in core all over the place is that the plugin manager got mostly replaced by the DefaultPluginManager which handles the caching instead of the decorator approach of before. $this->discovery has been good before (as it was the cache decorator),
so we probably failed to review the change properly.
Comment #12
berdirI guess the question is if we need a getDefinition($id) on the discovery, or if the discovery should only be responsible for returning an array of all definitions. Then it would be much more obvious to use $this->getDefinition() instead of $this->discovery->getDefinition(). That would obviously be an API change, so maybe just document it properly..
Comment #13
catchI'd be OK with an API change if it stops this.
Comment #14
yched commentedAgreed with #12 that there shouldn't be a way to ask the discovery about a single definition, this should be the manager's task, discovery now is only about finding all.
That would mean removing getDefinition() from DiscoveryInterface (and from existing discovery classes / decorators ?), and adding it to PluginManagerInterface (that would be the only explicit method in there, PluginManagerInterface currently only extends other interfaces...)
Comment #15
berdirOk, opened #2052921: Document the complexities of the DefaultPluginManager
Comment #16
neclimdulSkimming the patch, all the changes seem to be to managers that are hard coding logic they copied out of factories instead of using factories. I don't understand why that's being done as I don't see any specific logic in any of them to justify it.