Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Now that #1973618: DIC: Lazy instantiation of service dependencies (ProxyManager for "proxy services") has landed, we finally have the ability to mark services as lazy. That was the infrastructure issue. This issue is about determining which services should be lazy, by doing the necessary profiling work.
Proposed resolution
Mark more services as lazy.
Remaining tasks
- (done) profiling. see #24
- reviews
User interface changes
None.
API changes
None.
Comment | File | Size | Author |
---|---|---|---|
#32 | classes-admin-reports-status-php.txt | 13.97 KB | Fabianx |
#32 | profile_to_determine-2407177-32.patch | 4.02 KB | Fabianx |
#18 | interdiff.txt | 439 bytes | dawehner |
#18 | 2407177-18.patch | 6.04 KB | dawehner |
#16 | 2407177-16.patch | 6.47 KB | dawehner |
Comments
Comment #1
dawehnerThis is the patch I tried to test (enabled proxy for all the services), but it failed on the loading of the dumped container, I don't understand why yet.
Comment #2
jibranComment #4
dawehnerAlright, no idea is bugfree, here are two bugs which came out of this so far.
Comment #5
dawehnerEnable all of them is tricky, here is a list of classes I at least had to exclude for now, as they don't use an interface.
Comment #6
alexpottDiscussed with @xjm, @catch, @webchick, and @effulgentsia. Changing the issue title to reflect focus of the issue. According to @effulgentsia d8's bootstrap is still 3 ro 4 times slower than d7. This is one approach to solving that performance regression.
Comment #7
dawehnerHere is a list of classes which is loaded on the most simplest page you can imagine:
admin/reports/status/php
Some random ideas, which should probably be moved into their own subissues
they are loaded, maybe they should be marked as lazy
theme.negotiator.system.batch
have to be loaded.Comment #8
Berdir+ 1 on dropping timer.
- private key change sounds interesting, but would be an API change.
Actually, we want to do the opposite, enable by default, without configuration checks: #2368987: Move internal page caching to a module to avoid relying on config get on runtime.
That list is interesting. Any chance you can provide a tree-like output, based on how they are created through the container? That would help with understanding what is needed why.
Comment #9
Wim LeersAnd doing that will allow any site that doesn't use the page cache to save those 10 classes.
(BTW: those 10 classes are 1) only a small fraction of the grand total of classes, 2) the page cache itself is very fast, and on a page cache hit, these classes are also loaded, so that's definitely not going to make a huge difference for overall bootstrap performance.)
Comment #10
yched CreditAttribution: yched commentedWoah. Scary :-(
"Make the creation of the discovery objects lazy in the default plugin manager" sounds like something we should totally do...
Comment #11
BerdirAttached is my version for that output, patch is the hacks that i used to generate it. The classes are indented based on the "container recursion level". That makes it visible which service caused which class to be loaded.
Comment #12
Fabianx CreditAttribution: Fabianx commentedHere is my classes with usage count gotten via XHProf for anonymous stock front page:
Starts with:
"-" == class used 0 times, potentially problematic
"+" == class used 1 times
"*" == class used more than 1 times
"=" == is a service
Removed traits and interfaces and did not count __construct obviously.
Patch attached to create output, too.
(Edit: Review with dreditor to see problematic (red) and less used (green) services on a glance).
Comment #13
dawehnerReally nice idea to leverage + and -!!
Just some random comments.
So lock should be lazy by default?
I'd argue that the entire router.builder should be lazy, but for now the MatcherDumper should be.
Note: #356399: Optimize the route rebuilding process to rebuild on write would also remove the initialization in the first place.
The script seems to include base classes
Maybe this is a sign that param converter should be loaded lazy again.
Given that the bare html page renderer should be needed on just a really limited amount of pages, it should be lazy.
So module installer, config installer, info_parser certainly falls into the category of: just used rarely.
that one certainly should also be lazy. Its just needed for UI purposes, either in admin/people/... or in the views UI.
Comment #14
Wim LeersFabianx++ — clever usage of our existing infra :D
Comment #15
Fabianx CreditAttribution: Fabianx commented#13:
Yes, that is pretty hard to check here, with the reflection class, I could get the base class, but the problems are calls to the base class:
To which class would you count those?
--
Can you do a patch for the services now found that could be lazy?
Every non-loaded class is a _huge_ win, so lets focus on things with large dependency chains as we need to load the proxy dumped class anyway.
Comment #16
dawehnerHere are a couple of those services marked as lazy.
Comment #18
dawehnerAgain ...
Comment #20
yched CreditAttribution: yched commentedAs @dawehner pointed above, most (plugin) Discovery objects are created but not used, since the definitions are cached anyway.
Comment #21
dawehnerI'm not sure whether its right to exclude the
config.manager
from being lazy, but the error message just scares the hell out of me,and marking the other ones lazy is some progress for itself.
Comment #23
dawehnerQuickly rerolled.
Comment #24
dawehnerDid some quick profiling for the following usecases:
I'm have profiled the entire request, with opcache as well as the apcu based classloader enabled.
Absolute numbers
Comment #25
YesCT CreditAttribution: YesCT commentedremoving needs profiling tag (unless there were some other cases that needed profiling?)
Comment #26
dawehnerFabian asked me to create a separate issue: #2454287: Make a couple of services lazy to get the current changes in
Comment #27
Fabianx CreditAttribution: Fabianx commentedBack to active here then, lets get more profiling for other scenarios done after #2454287: Make a couple of services lazy is in.
Comment #28
dawehnerOther ideas for scenarious:
Comment #29
effulgentsia CreditAttribution: effulgentsia at Acquia commented@dawehner or @Fabianx: can you provide an updated list along the lines of #7 or #12 for the admin/reports/status/php scenario? Seems like our bootstrap is still too slow (relative to D7). Maybe there's nothing left that can be made lazy for that scenario, but a list of loaded classes could perhaps point to some other optimizations we should open issues for?
Comment #30
Fabianx CreditAttribution: Fabianx commented#29 It is Fabian_x with lowercase x ... *grmbl* :-D
Yes, can provide new classes for the scenario if dawehner does not beat me to it :).
Comment #31
effulgentsia CreditAttribution: effulgentsia at Acquia commentedOops. Sorry. Edited #29 to fix that.
Comment #32
Fabianx CreditAttribution: Fabianx for Drupal Association commentedRe-rolled and attached classes.txt for /admin/reports/status/php
Comment #33
dawehnerOpened up an issue for some of them, see #2463343: Lazy load typed config related services. but the result is not really positive yet.
Comment #34
borisson_Comment #35
borisson_I tested this by using boom to do 100 requests with a concurrency of 2 to my local machine with page cache disabled.
The command I used is this one:
$ ~/go/bin/boom -n 100 -c 2 http://d8.dev/node/4
I used the 90th percentile of time distribution.
The results I have are these:
With all those services made lazy though I get an interesting result. The result is then 0.6296 secs.
Comment #36
BerdirWe can't make the services lazy that we know that we will call, that makes performance worse, not better. config.storage.schema is different, there's an issue for that.
Note: Testing concurrency > 1 is just testing your system and not the code. How many requests in parallel are processed doesn't matter how long a single request has, if anything, it makes it a bit slower when it has to wait.
Comment #37
dawehnerRight, as we deal with potential just small changes, using an external HTTP based tool is IMHO the wrong approach.
Nonetheless its great to see that marking
config.storage.schema
is quite helpful in terms of performance, itself.Comment #38
effulgentsia CreditAttribution: effulgentsia at Acquia commentedDetermining which services should be lazy seems like a subset of #2470679: [meta] Identify necessary performance optimizations for common profiling scenarios, so raised that one to critical. Marking this as fixed rather than duplicate, because of the early work done in this issue that resulted in us making some services lazy already.