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
PHP user sort functions expects -1, 0 or 1. Since PHP 7.0 there's optimized "spacehip" operator <=>
so core could optimize few places using it
Proposed resolution
core/modules/language/src/HttpKernel/PathProcessorLanguage.php
- get rid of custom comparison and allocating memory for local variables in inline sorting
core/modules/layout_builder/src/Section.php
- makes sorting more predictable (same weights will return 0 as user sorts expects) and faster
Remaining tasks
agree or improvement, review, commit
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
N/a
Comment | File | Size | Author |
---|---|---|---|
#31 | 3161223-31.patch | 11.56 KB | andypost |
#16 | interdiff.3161223.15-16.txt | 6.03 KB | longwave |
Comments
Comment #2
Hardik_Patel_12 CreditAttribution: Hardik_Patel_12 at Portage CyberTech for Drupal India Association commentedKindly review.
Comment #4
cilefen CreditAttribution: cilefen as a volunteer commentedComment #5
andypostno reason for
()
hereComment #6
andypostThere's actually only one place to fix
core/modules/layout_builder/src/Section.php
Probably second hunk in
PathProcessorLanguage.php
needs separate quickfix (optimization) to remove useless declaration of variables to compare - so I left it hereOther places are reverted because before 1/-1 there's check for equal value
Comment #7
alexpottNone of these changes are necessary for PHP 8 compatibility as far as I can see. None of these are returning a bool. The issue summary needs to be updated. The changes are fine but things should be accurate.
Comment #8
alexpottAlso the title needs fixing because neither of these methods return a bool - hence they do not trigger a warning.
Comment #9
andypostI thing it's just hard to catch same weights in LB section
But ++ to update summary
If weights are the same this fix is valid
Comment #10
andypostRe-titled and update IS
Comment #11
Krzysztof DomańskiComment #12
longwaveThere are a bunch more it looks like we can do, if we think this should be done everywhere:
core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
237: return ($a_weight < $b_weight) ? -1 : 1;
core/lib/Drupal/Core/Language/Language.php
163: return ($a_weight < $b_weight) ? -1 : 1;
core/lib/Drupal/Core/Routing/RouteProvider.php
395: return (int) $a['fit'] < (int) $b['fit'] ? 1 : -1;
core/lib/Drupal/Component/Utility/SortArray.php
129: return ($a_weight < $b_weight) ? -1 : 1;
core/modules/shortcut/src/Entity/Shortcut.php
188: return ($a_weight < $b_weight) ? -1 : 1;
core/modules/filter/src/FilterPluginCollection.php
97: return $a->weight < $b->weight ? -1 : 1;
core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php
56: return $display1['position'] < $display2['position'] ? -1 : 1;
core/modules/help_topics/src/Plugin/HelpSection/HelpTopicSection.php
186: return $a->getPluginId() < $b->getPluginId() ? -1 : 1;
core/modules/image/src/ImageEffectPluginCollection.php
31: return ($a_weight < $b_weight) ? -1 : 1;
core/modules/tour/src/Entity/Tour.php
129: return ($a->getWeight() < $b->getWeight()) ? -1 : 1;
core/modules/views/src/ViewsData.php
307: return $a['weight'] < $b['weight'] ? -1 : 1;
310: return $a['title'] < $b['title'] ? -1 : 1;
core/modules/views/src/ViewsDataHelper.php
179: return $a_group < $b_group ? -1 : 1;
185: return $a_title < $b_title ? -1 : 1;
core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php
115: return $order * (($a[$column] < $b[$column]) ? -1 : 1);
core/modules/views/tests/src/Functional/ViewTestBase.php
88: return $order * (($a[$column] < $b[$column]) ? -1 : 1);
core/modules/views/views.views.inc
282: return $label_counter[$a] > $label_counter[$b] ? -1 : 1;
core/modules/search/src/Entity/SearchPage.php
219: return ($a_status > $b_status) ? -1 : 1;
Comment #13
andypost@longwave actually not, because other places using different comparison when values are equal
Comment #14
longwaveWe still can use spaceship operator in most cases even if the == 0 comparison is done elsewhere?
Also surely e.g.
can just become
Comment #15
andypostChecked all places again and updated ones where it possible
@longwave Thank a lot for idea
Comment #16
longwaveWe can change them all, even if the 0 value is not needed.
Comment #17
dwwMost of this looks like a great cleanup/simplification. I didn't know about the "spaceship" until I saw this. Cool. ;)
Obvious win.
Less obvious. ;) The current code will return 1 if the weights are the same. New code will start returning 0. Is this really safe / desirable?
@longwave, would you be willing to clarify: "even if the 0 value is not needed."? Yes, all the tests are still passing, so that's good. But I'm not sure the full "change them all" approach is really safe.
Thoughts?
Thanks,
-Derek
Comment #18
longwaveRe #17.2, if you look at the wider context:
The spaceship operator can never return 0 as we already handled the equality case above; it can only ever return -1 or 1 now. This is the same for all the cases here, except where we explicitly returned 0 in the equality case and then we can use the spaceship operator alone, as in #17.1.
Comment #19
alexpottI'm not in favour of these changes where the spaceship operator can never return 0 because of the surrounding context. The current code is more explicit about this. Whereas the new code obfuscates it for no reason. I think all of the above changes should be reverted.
#17.1 is great and we should be making changes like that.
Comment #20
longwaveFWIW for me the spaceship operator is more explicit, because I don't have to remember which way round is < and > vs -1 and 1, e.g:
Here it is much more obvious to me that we are sorting
$a_group
before$b_group
but$label_counter[$b]
before$label_counter[$a]
- ie the latter is a reverse sort. In other words: the magic constants of -1 and 1 are removed and the argument order always tells me which way we are sorting.Comment #21
andypost@alexpott that's for readability reasons of code, moreover change record could propose usage of <=> on core (maybe it needs policy issue?)
@dww #17.2 that's how user sorts should work - return 0 when items are equal, also sorts becomes more predictable in php 8
Comment #22
alexpott#20 is a good point. Hmmm... I think both points (#20 and #19) are valid. But #20 is slightly more compelling. So let's ignore #19 for now unless a more compelling case can be made for it.
Comment #23
alexpottComment #24
dww#18 re #17.2: Sorry I didn't apply and check wider context. Thanks!
#20: +1
#21: re: #17.2: Absolutely. User sorts should work like that. But I've been bitten so many times fixing bugs in core where the change "might be disruptive" that I'm now shy about behavior changes. ;) +1 to fixing these if allowed.
#22: I think #20 is more compelling, too. To address #19 perhaps we could adopt a comment convention in those (rare?) cases. If it really matters, would probably be clearer than having to parse surrounding context to check. E.g.:
(or whatever).
Thanks everyone!
-Derek
Comment #25
jungleShould we include strnatcasecmp() and similar ones in scope here? For instance:
Comment #26
longwaveNo, we need to be careful because
strnatcasecmp()
andstrtolower()
/<=>
do not sort identically:I think we should leave these alone as
strnatcasecmp()
already tells you how we are sorting,<=>
is no clearer or more readable to me.Comment #27
jungle@longwave, thanks for your reply!
I am about to agree on this, but code should be self-explained as possible.
It's true. However, as the spaceship operator is new to me, the same as @dww (see #17), when I see a usage of it, it gives me a hint that the possible values/return values are -1, 0 and 1. If the possible values/return values are -1 or 1, in my mind
?:
is better. Less confusing or less thinking while reading the code. I do not think most of people could get the info of "which way we are sorting" from the argument order if no extra explanation/comment.So +1 to #19 to revert non-obvious
<=>
-applicable changes.Comment #28
andypostPHP 8 got rfc for sorts, so this clean-up can affect ordering as #26 said
Comment #31
andypostJust re-roll for 9.3, I still see no much reasons to revert "non-obvious" changes as it much more readable comparing to 1/-1 magic numbers
Re #24 not sure comment will help as few lines above there's comparison for equality
Comment #32
joachim CreditAttribution: joachim as a volunteer commentedLGTM.
Comment #33
daffie CreditAttribution: daffie commented+1 for RTBC.
Comment #35
daffie CreditAttribution: daffie commentedBack to RTBC.
Comment #36
alexpottApplied using --3way and it worked great.
Committed b69a33e and pushed to 9.3.x. Thanks!