Problem/Motivation
We suspect that Cache::mergeContexts()
, Cache::mergeTags()
and Cache::mergeMaxAges()
can be optimized by no longer supporting N arguments (using func_get_args()
), but instead only accepting 2 arguments (which is the most common case) and then optimizing for that.
Proposed resolution
Optimize for 2 arguments.
Profiling: see #9.
Remaining tasks
None.
User interface changes
None.
API changes
Yes: Cache::mergeTags
, Cache::mergeContexts
and Cache::mergeMaxAges
now all only support 2 arguments instead of the previously supported n arguments.
Data model changes
None.
Beta phase evaluation
Issue category | Task because it optimizes performance in a very, very hot code path. |
---|---|
Issue priority | Major because it has a significant performance impact. |
Prioritized changes | The main goal of this issue is performance |
Disruption | Minimally disruptive for core/contributed and custom modules because 99% of the time, the functions are called with 2 parameters. However, any places where these functions are called with >2 parameters, they will need to be updated. |
Comment | File | Size | Author |
---|---|---|---|
#73 | optimize-2471232-73.patch | 25.93 KB | borisson_ |
#73 | interdiff.txt | 3.07 KB | borisson_ |
#69 | interdiff.txt | 1.64 KB | borisson_ |
#69 | optimize-2471232-68.patch | 25.91 KB | borisson_ |
#65 | optimize-2471232-65.patch | 24.27 KB | borisson_ |
Comments
Comment #1
bogdan.racz CreditAttribution: bogdan.racz commentedComment #2
Wim LeersCan you give some kind of progress indication, @rmboogie? :)
Comment #3
bogdan.racz CreditAttribution: bogdan.racz commentedStill working on it. Yesterday I had some problems with the xhprof installation on mamp and osx.
I already made the modifications. Roughly the code for one of the function looks this:
I left 3 arguments because of the following call:
Tests/Entity/EntityCacheTagsTestBase.php @400, @410
Is this the right way to approach it? I was going to profile it.
Comment #4
Wim LeersAlright, just wanted to make sure you're 1) not stuck, 2) still working on it :)
That looks like a step in the right direction, but you're accepting three parameters, not two. I'd call them
$a
and$b
.Comment #5
bogdan.racz CreditAttribution: bogdan.racz commentedI have added the patch, but haven't managed to make a profile test.
Please somebody, add some xhprof results.
Comment #6
mariancalinro CreditAttribution: mariancalinro commentedI will do some profiling for this.
Comment #7
joshi.rohit100I think, we also need to update the commenting part.
Comment #8
bogdan.racz CreditAttribution: bogdan.racz commentedI have updated the methods comments. Please review.
Comment #9
mariancalinro CreditAttribution: mariancalinro commentedI did some tests. I run each function 10.000 times, and with or without the pach, and here are the results:
mergeContexts
Before patch
10000 runs, total run time 3.8855350017548, max run time 0.0035789012908936, min run time 0.00031113624572754.
After patch
10000 runs, total run time 3.4474279880524, max run time 0.0020530223846436, min run time 0.00027203559875488.
mergeTags
Before patch
10000 runs, total run time 3.330482006073, max run time 0.0016181468963623, min run time 0.00025105476379395.
After patch
10000 runs, total run time 2.8155419826508, max run time 0.0014889240264893, min run time 0.00021004676818848.
mergeMaxAges
Before patch
with Cache::PERMANENT as one of the parameters
10000 runs, total run time 2.1057970523834, max run time 0.001248836517334, min run time 0.00015687942504883.
without Cache::PERMANENT
10000 runs, total run time 1.4308922290802, max run time 0.0014550685882568, min run time 9.1075897216797E-5.
After patch
with Cache::PERMANENT as one of the parameters
Cache::PERMANENT is first_parameter:
10000 runs, total run time 0.69816279411316, max run time 0.001704216003418, min run time 3.0994415283203E-5.
Cache::PERMANENT is second_parameter:
10000 runs, total run time 0.78123903274536, max run time 0.0024521350860596, min run time 3.2901763916016E-5.
without Cache::PERMANENT
10000 runs, total run time 0.9782989025116, max run time 0.00097084045410156, min run time 5.1021575927734E-5.
Comment #12
mariancalinro CreditAttribution: mariancalinro commentedreroll
Comment #14
Wim LeersNice! Those numbers look promising :)
If we can now get this green, then we're good to go :)
Comment #15
bogdan.racz CreditAttribution: bogdan.racz commentedComment #16
mariancalinro CreditAttribution: mariancalinro commentedThe patch fails because there are some places that use more than 2 arguments for Cache::mergeTags method.
Here is one example in EntityCacheTagsTestBase.php @337
I suggest further analysis of the opportunity of this optimization for Cache::mergeTags.
Comment #17
Wim LeersYes, those calls simply need to be updated, to call
Cache::merge*()
multiple times. Almost all of those >2 cases are in tests anyway.Comment #18
JeroenTCalled Cache::merge*() multiple times where it used more than 2 arguments.
Patch attached.
Comment #19
bogdan.racz CreditAttribution: bogdan.racz commented@JeroenT you can also update the comments as here, if it is ok.
Comment #20
JeroenT@rbmboogie,
I'm sorry, I took #12 as startpoint.
I created a new patch.
Comment #21
bogdan.racz CreditAttribution: bogdan.racz commentedOne small typo coming from my patch, notice there are 2 points :)
Comment #22
Wim LeersComment #25
JeroenTFixed comment + some failing tests.
Comment #27
JeroenTComment #29
bogdan.racz CreditAttribution: bogdan.racz commentedAs far as I have checked, at least the following tests:
fail because of the following verification in EntityCacheTagsTestBase in line @426:
$this->verifyPageCache($nonempty_entity_listing_url, 'HIT', $nonempty_entity_listing_cache_tags);
Currently, I don't have more time to investigate the issue, as I will be leaving back home from the Drupal Dev Days.
If the issue is still unsolved by Monday, I can check it again.
Thanks for all the help.
Comment #30
JeroenT@rbmboogie,
Thanks! I think i fixed the last failing tests now.
Comment #31
cilefen CreditAttribution: cilefen commentedComment #32
ruha CreditAttribution: ruha commentedAt DrupalCon La, workingon reroll
Comment #33
ruha CreditAttribution: ruha at Scout Marketing commentedRerolled patch with 2 merge conflicts
Merge conflict in core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php line 55
Merge conflict in core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php line 100
Comment #35
borisson_Tried applying the patch by JeroenT again with PhpStorm, got no conflicts. Patch attached.
Comment #37
borisson_This should resolve part of the failures.
Comment #39
borisson_This should fix all remaining failures.
Comment #40
sorressean CreditAttribution: sorressean at Acquia commentedFixed a couple points with this patch:
1. Brought the patch up to date with latest commits.
2. Optimized the to avoie multiple frequent calls to
Cache::mergeTags
. the goal was to eliminate multiple calls that did not need to occur until after the array had been built for the last time.Comment #41
Wim LeersWow, so many places that weren't yet using the right API! Thanks, great catches :)
Comment #42
borisson_Cache::mergeTags should only have 2 arguments, so these should split up into multiple calls
Same as 1.
Same as 1.
Comment #44
sorressean CreditAttribution: sorressean at Acquia commentedUpdated to fix a couple stupid syntax errors which were preventing tests from running. Sorry about that.
I'm not sure what comments 42 and 43 are referring to, as that code has been fixed with my patch. Unless there are any issues, I will promote this to needs review after tests have hopefully passed.
Comment #45
sorressean CreditAttribution: sorressean at Acquia commentedComment #46
martin107 CreditAttribution: martin107 commentedMoving to needs review to trigger the testbot.
Comment #49
borisson_I noticed a couple of weird things in the patch file that weren't in the interdiff so I went ahead and fixed those.
Comment #53
tim.plunkettMight as well use ===
I don't understand these final calls with one argument. They look like a mistake. Can we either remove them or document them?
We don't do inline comments like this, and the second element is missing a trailing comma
Comment #54
borisson_Fixed test failure in TrackerTest.
Regarding comments from #53
Comment #55
tim.plunkettOh for #53.2, you're right about the commas, I misread it as part of an array, not in a function call, so you are correct.
Comment #56
daffie CreditAttribution: daffie commentedLooks good to me. Just two remarks:
Can we add type hinting to the parameters. In this way we make sure that the parameters are an array. Like:
(array $a = array(), array $b = array())
Can you explain why you add this change. I do not think it is necessary.
Comment #57
JeroenTMade changes as suggested by daffie in #56.
Comment #58
JeroenTThis is the right interdiff...
Comment #60
borisson_Patch applies again now, changed the typehinting to use short array syntax (array $a = [], array $b = []). I had to make a change in the TrackerTest as well to also check for the 'user.node_grants:view' cache context.
Comment #61
Wim Leerss/context/contexts/
s/tag/tags/
s/find/merge/
Can we please put each of these on single lines? This is overly verbose.
This becomes an enormous statement. Let's put each merge statement on a single line, for legibility.
Let's do that everywhere where we merge >2 things in tests. Otherwise those tests become quite confusing/painful to read.
Comment #63
borisson_Fixed test failures and remarks from Wim in #61. I'm not really happy with the changes in EntityCacheTagsTestBase for $page_cache_tags. It does make sense to fix the mergeTags call but the merged comment doesn't feel right.
Comment #64
Wim LeersI agree that this looks worse. Let's evaluate it case-by-case then. Let's revert this back to the previous state.
This however, is much clearer!
Comment #65
borisson_I couldn't go for a straight revert of the previous state, mergeTags was getting 3 arguments instead of 2. I think this solution is even more readable than the original solution.
Comment #68
Wim LeersYep, that's exactly what I meant :)
Comment #69
borisson_Fixes the failures in FrontPageTest.
Comment #72
Wim LeersI already did a high-level IS update, but needs to be refined a bit more. Once that's done, and the nits below are fixed, this is RTBC.
s/$expectedTags/$expected_tags/
Again.
Same.
Comment #73
borisson_I updated the IS and added a beta evaluation. I think the beta evaluation is correct but I'm not sure.
Also fixed the nits from #72.
Comment #74
Wim LeersComment #75
Wim LeersMade some further beta evaluation adjustments. Looking great! Thanks :)
Comment #76
catchCommitted/pushed to 8.0.x, thanks!