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
Currently commerce_line_item_delete_references() will remove the line item from all entities that reference it. The problem is most of the time if you delete more than one line item on the same order you will call entity_save() multiple times.
Proposed resolution
Instead of saving the order over and over again for each order, return a list of entities needing saving after and loop through that list.
Comment | File | Size | Author |
---|---|---|---|
#24 | 2653904-24.commerce_line_item_delete_references.patch | 2.66 KB | rszrama |
| |||
#12 | improve-2653904-12.patch | 2.89 KB | joelpittet |
| |||
#8 | Shopping_cart___Site-Install.png | 74.55 KB | mglaman |
#3 | XHProf__Hierarchical_Profiler_Report.png | 268.6 KB | joelpittet |
#2 | improve-2653904-2.patch | 2.78 KB | joelpittet |
|
Comments
Comment #2
joelpittetI've defaulted this to save for BC, yet there seems to be only one call to this function.
Comment #3
joelpittetAdding profiling to show the savings.
Comment #4
joelpittetComment #5
joelpittetFor the profiling, I had 40 order discounts on an order and that was just the ajax block loading the order summary firing discount refresh. It's not the whole solution but this provides some huge benefits to a solution.
Comment #6
mglamanOkay, I originally went from "woah this breaks expectations" to "oh, now I get it!" Essentially the function's operation is unchanged for existing implementations. The controller sets the new flag parameter to FALSE. This allows it to only run the save operation on entities at a minimal amount. Otherwise we could run the save a whole bunch of times.
Comment #7
mglaman$skip_save = FALSE ? and if false save, matches how core does order status updates.
Whether* (:
Comment #8
mglamanHere's some more data. Order with 9 order discounts.
Without patch: https://blackfire.io/profiles/2b13e5f8-d28f-46fd-b6fc-951fea90a1a8/graph
With patch: https://blackfire.io/profiles/30190eb3-1a36-48cb-8d7e-3fe99c2e3bcc/graph
commerce_discount_order_refresh was 200ms faster.
commerce_cart_refresh was 1.3s to 894ms
There's obviously issues in Discount, but this makes it a lot better.
cart in question
Comment #9
joelpittetThanks for testing @mglman and reviewing. I think I thought of a scenario where this could be bad and need to test it. But because the order entities aren't passed by reference each time and got with entity_load(), this could lead to maybe stale references. I think we'll need some tests to make sure we aren't leaving them behind.
And if that is the case, I think creating a new function instead of shoehorning the logic in this one may be worth while.
Comment #10
mglamanBut wouldn't this always be a risk? The loaded entities will still have hit the controller's internal static cache. The only issue is if someone edited the order and didn't commit their changes, it seems. I'm not sure how what's happening here is any different than what's existing, except we're providing a way to reduce the number of saves.
Comment #11
joelpittet@mglaman I may be wrong but look at this piece of the code.
Specifically inside of
commerce_entity_reference_delete()
, note that all it does is remove the deltas from the field names on the passed in$entity
reference. Because the$entity
reference is being loaded incommerce_line_item_delete_references
and not the controller that we moved the save to, we lose that change outside the function... right?Comment #12
joelpittetOk this is inlined to avoid lost of changes of each entity when it get's clobbered by the new loaded entities.
Likely needs some refactoring.
Comment #13
joelpittetMoving this outside the nested loops should provide some CPU performance improvements as well.
Comment #14
mglamanDo we even need to load? We have the entity type and the entity ID.
If the type and entity ID are not set, add. This way we can actually stop loading duplicates. I get it shouldn't be that big of a deal because of static caches, but it could streamline the process some.
Comment #15
mglamanNevermind my last comment. This is done to ensure proper object references.
Comment #16
joelpittetcommerce_field_info()
saved only maybe 2ms, but still this patch is still saving me ~5s load time which is about 90% improvement from what was insidecommerce_line_item_delete_references()
And I'm quite confident we aren't missing any references removal saves with the latest patch.
Comment #17
smccabe CreditAttribution: smccabe as a volunteer and at Acro Commerce commentedRefactored the patch slightly to remove unnecessary entity loads, otherwise I think it's good to go! Does this mean I've made it so I can't RTBC? hmm...
@joelpittet, if you still have your profiling environment up, mind running it through again?
Comment #18
joelpittetCould you post an interdiff on that change please?
I can likely get a profiling scenario close, just want to read over the changes first.
Thanks for the review @smccabe
Comment #19
smccabe CreditAttribution: smccabe as a volunteer and at Acro Commerce commentedComment #20
smccabe CreditAttribution: smccabe as a volunteer and at Acro Commerce commentedLast one didn't upload right, here's the proper one.
Comment #21
joelpittet@smccabe thank you for the interdiff. I couldn't follow the change. Maybe you can run me through the change at midcamp?
There are some coding standard nits to pick in there too but rather grasp the change before I look at those
Comment #22
smccabe CreditAttribution: smccabe as a volunteer and at Acro Commerce commentedTalked w/ @joelpittet, turns out to be a really really edge case for my change, so more likely to cause performance issues than fix it. Putting this to RTBC with #12
Comment #23
smccabe CreditAttribution: smccabe as a volunteer and at Acro Commerce commentedComment #24
rszrama CreditAttribution: rszrama at Centarro commentedGonna commit this light reroll with the else hunk removed from the $entities_to_save array. Added some comments further explaining the rationale for the patch at the top of the try block.
Comment #25
rszrama CreditAttribution: rszrama at Centarro commentedCommitted.