Commit 3ede6199 authored by webchick's avatar webchick

#619666 follow-up by effulgentsia: Make performance-critical usage of drupal_static() grokkable.

parent 37fcdbc6
......@@ -2188,16 +2188,35 @@ function registry_update() {
* function is called many times (100+) during a single page request, so
* every microsecond of execution time that can be removed from the function
* counts. These functions can use a more cumbersome, but faster variant of
* calling drupal_static(). For benchmarks and background on this variant,
* please see http://drupal.org/node/619666.
* calling drupal_static(). It works by storing the reference returned by
* drupal_static() in the calling function's own static variable, thereby
* removing the need to call drupal_static() for each iteration of the function.
* Conceptually, it replaces:
* @code
* $foo = &drupal_static(__FUNCTION__);
* @endcode
* with:
* @code
* // Unfortunately, this does not work.
* static $foo = &drupal_static(__FUNCTION__);
* @endcode
* However, the above line of code does not work, because PHP only allows static
* variables to be initializied by literal values, and does not allow static
* variables to be assigned to references.
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.references
* The example below shows the syntax needed to work around both limitations.
* For benchmarks and more information, @see http://drupal.org/node/619666.
*
* Example:
* @code
* function user_access($string, $account = NULL) {
* // Use the advanced drupal_static() pattern, since this is called very often.
* static $drupal_static = array();
* isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
* $perm = &$drupal_static[__FUNCTION__];
* static $drupal_static_fast;
* if (!isset($drupal_static_fast)) {
* $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
* }
* $perm = &$drupal_static_fast['perm'];
* ...
* }
* @endcode
......
......@@ -2278,9 +2278,11 @@ function format_interval($timestamp, $granularity = 2, $langcode = NULL) {
*/
function format_date($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL) {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$timezones = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['timezones'] = &drupal_static(__FUNCTION__);
}
$timezones = &$drupal_static_fast['timezones'];
if (!isset($timezone)) {
global $user;
......@@ -2519,9 +2521,11 @@ function url($path = NULL, array $options = array()) {
global $base_url, $base_secure_url, $base_insecure_url;
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$script = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['script'] = &drupal_static(__FUNCTION__);
}
$script = &$drupal_static_fast['script'];
if (!isset($script)) {
// On some web servers, such as IIS, we can't omit "index.php". So, we
......@@ -4769,9 +4773,11 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
*/
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$functions = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['functions'] = &drupal_static(__FUNCTION__);
}
$functions = &$drupal_static_fast['functions'];
// Some alter hooks are invoked many times per page request, so statically
// cache the list of functions to call, and on subsequent calls, iterate
......@@ -6271,9 +6277,11 @@ function drupal_check_incompatibility($v, $current_version) {
*/
function entity_get_info($entity_type = NULL) {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$entity_info = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['entity_info'] = &drupal_static(__FUNCTION__);
}
$entity_info = &$drupal_static_fast['entity_info'];
if (empty($entity_info)) {
if ($cache = cache_get('entity_info')) {
......
......@@ -450,9 +450,11 @@ function module_hook($module, $hook) {
*/
function module_implements($hook, $sort = FALSE, $reset = FALSE) {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$implementations = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['implementations'] = &drupal_static(__FUNCTION__);
}
$implementations = &$drupal_static_fast['implementations'];
// We maintain a persistent cache of hook implementations in addition to the
// static cache to avoid looping through every module and every hook on each
......
......@@ -46,9 +46,11 @@ function drupal_path_initialize() {
function drupal_lookup_path($action, $path = '', $path_language = NULL) {
global $language;
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$cache = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['cache'] = &drupal_static(__FUNCTION__);
}
$cache = &$drupal_static_fast['cache'];
if (!isset($cache)) {
$cache = array(
......@@ -260,9 +262,11 @@ function arg($index = NULL, $path = NULL) {
// information), it should be resettable anyway in case a module needs to
// free up the memory used by it.
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$arguments = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['arguments'] = &drupal_static(__FUNCTION__);
}
$arguments = &$drupal_static_fast['arguments'];
if (!isset($path)) {
$path = $_GET['q'];
......@@ -328,9 +332,11 @@ function drupal_set_title($title = NULL, $output = CHECK_PLAIN) {
*/
function drupal_is_front_page() {
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$is_front_page = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['is_front_page'] = &drupal_static(__FUNCTION__);
}
$is_front_page = &$drupal_static_fast['is_front_page'];
if (!isset($is_front_page)) {
// As drupal_path_initialize updates $_GET['q'] with the 'site_frontpage' path,
......
......@@ -719,9 +719,11 @@ function user_access($string, $account = NULL) {
// To reduce the number of SQL queries, we cache the user's permissions
// in a static variable.
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static = array();
isset($drupal_static[__FUNCTION__]) || ($drupal_static[__FUNCTION__] = &drupal_static(__FUNCTION__));
$perm = &$drupal_static[__FUNCTION__];
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
}
$perm = &$drupal_static_fast['perm'];
if (!isset($perm[$account->uid])) {
$role_permissions = user_role_permissions($account->roles);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment