Skip to Content

develCuy's blog

by Fernando Paredes García


4 good practices to speed-up your Drupal modules using cache

There are several ways to improve Drupal performance, and to be more honest, there are several ways to improve your infrastructure supporting Drupal (e.g. Web Server, MySQL Server, PHP opt-code cache, Varnish/Boost HTML cache, Application cache (Memcached/APC), Pagespeed (output compression/optimization), etc). You can also add gigs of RAM to your server, more processors and perhaps deploy your Drupal site on a cluster of 10+ dedicated servers. In the end, if your source code does not perform well, you will be just wasting CPU, Memory and Bandwidth and that equal money.

So, how to improve your code? There are several ways and this article will explore cache specifically. Following a series of good practices to improve your source code performance:

Practice #1: Make sure that your team understand about cache

According to Wikipedia, Cache "is a component that transparently stores data so that future requests for that data can be served faster. The data that is stored within a cache might be values that have been computed earlier or duplicates of original values that are stored elsewhere. If requested data is contained in the cache (cache hit), this request can be served by simply reading the cache, which is comparatively faster. Otherwise (cache miss), the data has to be recomputed or fetched from its original storage location, which is comparatively slower. Hence, the more requests can be served from the cache the faster the overall system performance is."

In Drupal source code, cache is stored in 2 places:
- PHP static memory
- Drupal cache

So make sure that your team understands what cache is and where to store/retrieve it.

Practice #2: Use PHP static memory to store cache

Focusing on PHP execution time, values can be stored in global variables, constants and static variables (hence the contradictory name). Drupal makes use of the last: static variables. In the source code of Drupal you will find several functions that make use of the PHP command: "static". It indicates that once a function is declared, PHP will create an static address of memory to store a value, such value is not cleared when function terminates, so the next time such function is called, the value can be retrieved again. That is the trick! IMHO they should be called persistent variables...

In short, a function that sets a value, can also get such value if makes use of static variables. See following example:

/**
 * Store a value in PHP static memory.
 */
function phpmemory_set() {
  static $value; // create a persistent memory address
  if (!isset($value)) { // make sure to not write the same value twice
   $value = "loads of data that taken hours to compute";
  }
  else {
    //  You got a value cached!
  }
  return $value;
}

/**
 * Read a value from PHP static memory. Just for semantic purposes.
 */
function phpmemory_get() {
  return phpmemory_set();
}

Above code defines two functions.
The first one: phpmemory_set() Creates a static variable, verifies if it is already assigned by a previous call, assigns it if it was not, and finally returns the value.
The second function phpmemory_get(), is just an alias of the first one, so you got a setter and a getter. Good job!

This technique works great with object definitions. The same as with classes, that are loaded to memory and then you instance them, PHP does not have to compile and recalculate all the code, it just looks for the definition directly from its internal memory and you get a value quite fast! Such a value could be an Array, an Object, a heavy text or so on. Such a value could also be data taken from an external source, perhaps a webservice or an SQL query, so you don't need to look for the value twice, consuming less time and bandwidth, just store such value in an static variable and you are done.

There is also a security mindset in this practice. Why not to use a global variable? because your function is the only one that should know how to retrieve such value. If that is not the case then feel free to use a global variable or perhaps a constant.

Practice #3: Use Drupal cache

Now focus on your Drupal deployed in a server. On every page request the same PHP code is executed, even if you stored your value in static memory, when you see the HTML it means that such value has been vaporized from PHP memory. Hopefully there are two nice functions that came to the rescue: cache_get() and cache_set(). So you can store your precious cache data outside of PHP memory and recover it when needed. That is the other trick! See the following example:

/**
 *  Store a value in Drupal cache.
 */
function drupalmemory_set() {
  $cache = cache_get('value');
  if (empty($cache->data)) {
    $value = "loads of precious data that taken years to compute";
    cache_set('value', $value);
  }
  else {
    $value = $cache->data; // You got a value cached in external memory!
  }
  return $value;
}

/**
 * Read a value from Drupal cache. Just for semantic purposes.
 */
function drupalmemory_get() {
  return drupalmemory_set();
}

Again, the function drupalmemory_get() does all the job. It asks for a value in Drupal cache, checks if the returned object contains a value and if not it sets the value, saves it to Drupal cache and finally returns it. The function drupalmemory_get() is just an alias. All this is because of the same principle: compute a value, store such value somewhere, recover such value later as much times as you can. The more you recover such value the better, you save more CPU!

Practice #4: Combine caches: Cache+Cache = Better performance (really?)

1 + 1 = 2 right? That is not always the case, so you should be careful and understand contexts and times. PHP memory and Drupal cache can be combined for better performance, but make sure that you are not just consuming more CPU for nothing. See the final example:

/**
 *  Store a value in PHP and Drupal cache.
 */
function combinedmemory_set() {
  static $value;
  if (!isset($value)) {
    $cache = cache_get('value');
    if (empty($cache->data)) {
      $value = "loads of precious data that taken light years to compute";
      cache_set('value', $value);
    }
    else {
      $value = $cache->data; // You got a value cached in external memory!
    }
  }
  return $value;
}

/**
 * Read a value from PHP and Drupal cache. Just for semantic purposes.
 */
function combinedmemory_get() {
  return combinedmemory_set();
}

That was not that hard right? The function combinedmomery_get() perhaps spends a bit more time to get the value from Drupal cache, but it makes sure to save the value in PHP memory, the we got a combination of two practices.

A suggestion: It is important to measure the usage of the values stored in cache and make use of Practice #2 or #4, Practice #3 is not used that often.

Conclusions

In this article you learned:
- What is cache and for what it is used
- How to use PHP static memory to store cache
- How to use Drupal cache
- How to combine PHP static memory and Drupal cache

Blessings!


Post new comment

The content of this field is kept private and will not be shown publicly.
  • You can use Markdown syntax to format and style the text. Also see Markdown Extra for tables, footnotes, and more.
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.