This is very preliminary but I figured someone might be bored over christmas and could provide some insight to me before I go digging into this too much.

Trying to debug site performance issues, I turn almost everything off and enable xhprof. Slowest function is t which was called 2000 times from system_region_list. That function was called 100 times by... drumroll.. context

The biggest culprits were
context_reaction_block::is_enabled_region (61 times) and
context_reaction_block::is_editable_region (40 times)

the 30 calls to system_region_list accounts for 30ms or 1/10 of the page load time.

Can the results of this function be cached by context?

Comments

joelcollinsdc’s picture

no idea if this is the right approach. this didn't same me the full 30ms i was expecting, i got about a 20-25ms performance bump.

joelcollinsdc’s picture

not sure if this is more or less right that the other way. seems more drupaly to me.

joelcollinsdc’s picture

Status: Active » Needs review
john morahan’s picture

I just ran into the same issue, and arrived at a similar patch; however, I was just thinking - would it be better to patch system_region_list() itself? That way we could cache for both REGIONS_ALL and REGIONS_VISIBLE while iterating over the list just once.

john morahan’s picture

Project: Context » Drupal core
Version: 7.x-3.x-dev » 7.x-dev
Component: Code » system.module
StatusFileSize
new1.58 KB

Something like this, perhaps.

Status: Needs review » Needs work

The last submitted patch, 1873450-cache-system-region-list.patch, failed testing.

john morahan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.85 KB
technicalknockout’s picture

Status: Needs review » Needs work

Sounds like this could improve the performance of the the core function, but could this be over-engineering the solution since it adds more complexity with a new layer of caching? It also sounds like it doesn't address what could be an inefficiency in the context module - does that module need to make 100 calls to this function in the first place?

john morahan’s picture

Well no, it doesn't *need* to in the sense that context could cache the result itself, as joelcollinsdc originally proposed. But putting the caching in the core function improves the performance regardless of the caller. It's called three times on a normal page view in vanilla core anyway.

john morahan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.85 KB

I think the performance of that first call can be improved, too.

technicalknockout’s picture

Status: Needs review » Needs work

@joelcollinsdc - maybe you could open up a new issue for the patch to the context module. It seems to me patching context would definitely be helfpul, but might be worth looking into why all the calls are being repeated in the first place and addressing there.

@John Morahan - the original function returns an empty array if the theme_key isn't set, where as the patch doesn't handle that condition. I think something like else {return array();} at the end would do it. unless you meant to change this?

joelcollinsdc’s picture

I think patching in core would be sufficient if there is buy-in to make that change. I didn't attempt to do it since it seemed that it was context that was abusing an uncached function, but if core even calls it 3x on a regular page load, yea it probably makes sense to cache it.

john morahan’s picture

@technicalknockout the original function returns an empty array if $themes[$theme_key] isn't set (where $themes is the return value from list_themes()). The patch first checks if $list[$theme_key] is set (where $list is the static cache variable), then later it initializes $list[$theme_key] to a pair of empty arrays, checks if $themes[$theme_key] is set before trying to populate them, and finally returns one of them at the end. So the overall behaviour should be unchanged. Or have you observed otherwise?

technicalknockout’s picture

yes, I see it initializes two empty arrays for keys REGIONS_ALL & REGIONS_VISIBLE, but there is nothing that restricts $theme_key from being passed in as something like $theme_key = 'nonsense'. In this case, the check <?php if (isset($themes[$theme_key])) ?> returns false and $list[$theme_key] remains unset. At the end the code still will attempt to reach into the uninitialized $list[$theme_key][$show]

john morahan’s picture

Nope. $list[$theme_key] is initialized before isset($themes[$theme_key]) is checked:

+    $list[$theme_key] = array(REGIONS_ALL => array(), REGIONS_VISIBLE => array());
+    $themes = list_themes();
+    if (isset($themes[$theme_key])) {
john morahan’s picture

It would indeed fail if $show was something other than REGIONS_ALL or REGIONS_VISIBLE, but as the API doc explicitly states "Possible values: REGIONS_ALL or REGIONS_VISIBLE", I don't think this case is worth worrying about.

technicalknockout’s picture

Sure, it's documented, but it is not enforced and the current behavior is to return an empty array. Maybe it's unlikely, but this change could cause a disruption for existing sites if for some reason they weren't following the API documentation. Is there an advantage to changing how this edge condition is handled currently?

john morahan’s picture

Version: 7.x-dev » 8.x-dev

Fair point. However, if people are happy in principle with addressing this in core, it would have to go into D8 first anyway, in which case it hardly matters how consistently we handle misuse of the API (though worth keeping in mind for a backport, obviously).

Also I see drupal_flush_all_caches() calls drupal_static_reset() in D8, so the explicit resets should not be necessary there.

I'll reroll it later.

technicalknockout’s picture

another point just thinking more about it (still in reference to D7, haven't looked at D8 at all on this yet) - this function does really little work. The work is done by list_themes and it caches its results internally already. Did you see a performance gain before & after the patch?

john morahan’s picture

StatusFileSize
new1.52 KB
new1.52 KB

Yes, though obviously it's more significant when the context module is involved (see joelcollinsdc's 30ms improvement right at the top; I got even better results), there is a slight improvement even with just core (total inclusive time for that function according to xdebug is 0.997ms before, 0.435ms after).

john morahan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.57 KB

d8 version, untested

Status: Needs review » Needs work

The last submitted patch, 1873450-cache-system-region-list-d8.patch, failed testing.

Mixologic’s picture

I just bumped up against the 2000 t's issue in my own xhprofs, searched in the context queue, found this: https://drupal.org/node/1688330

Definitely the right way to fix this is a drupal static inside of the system_region_list function.

The current behavior of system_region_list is to respond with all regions if there is no second argument, or if the second argument is "REGIONS_ALL". Any other second argument passed to system_region_list is going to behave as if "REGIONS_VISIBLE" was passed. So, to address @technicalknockouts concern, you could simply return

if ($show == REGIONS_ALL) {
  return $list[$theme_key][REGIONS_ALL];
}  else {
  return $list[$theme_key][REGIONS_VISIBLE];
}

Ideally this wouldn't be an argument dependent function at all and ought to be factored into two separate functions that each cache their static results like system_visible_region_list($theme_key) and system_region_list($theme_key);

To keep a backwards compatible API you could still allow for system_region_list to forward to system_visible_region_list if anything other than REGIONS_ALL is set for $show.

joelcollinsdc’s picture

Are there modules other than context that call this function many times? If not, maybe this makes more sense to move back to the context issue queue...

related/duplicate: #1688330: Reduce number of calls to system_region_list

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Issue summary: View changes
Issue tags: +Bug Smash Initiative

There has been no activity here for 9 years.

Is this still a problem?

If you are experiencing this problem on a supported version of Drupal reopen the issue, by setting the status to 'Active', and comment on what still needs to be done.

Thanks!

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mstrelan’s picture

Status: Needs work » Postponed (maintainer needs more info)

Postponed as per #36

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

Since there's been no follow up going to close out. If still a valid bug in D11 please re-open

Thanks all

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.