[wp-trac] [WordPress Trac] #21320: Speed up WP_Object_Cache::_exists()

WordPress Trac wp-trac at lists.automattic.com
Fri Jul 20 04:17:59 UTC 2012


#21320: Speed up WP_Object_Cache::_exists()
-------------------------+-----------------
 Reporter:  nacin        |      Owner:
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  3.5
Component:  Cache        |    Version:  3.4
 Severity:  normal       |   Keywords:
-------------------------+-----------------
 Both kurtpayne and I have noticed that the _exists() method is way slower
 than it should be. It only contains three PHP functions: isset(),
 is_array(), and array_key_exists(). Yet frequently, I see 5-10% of a
 pageload spent in cache.php, and somewhere around 30-40% of that spent in
 _exists() (so > 2% overall).

 In this one example, _exists() was called 2507 times, so every little bit
 counts. 2295 of them came from get(), 212 from add(). It is therefore
 quite obvious that we rely heavily on our local cache.

 Based on that assumption, we can make some changes to speed up this
 conditional:
 {{{
 isset( $this->cache[$group] ) && is_array( $this->cache[$group] ) &&
 array_key_exists( $key, $this->cache[$group] );
 }}}

 First, the is_array() can go. Never would the $group key exist with the
 value of anything other than an array, and cache.php makes this assumption
 elsewhere.

 isset() is mighty fast for a language construct, while arrays in PHP are
 generally slow. The next step would be to remove array_key_exists(), but
 we need to do so without regressing #20004.

 So, we can pre-empty array_key_exists() with an isset() check first. If
 the key is set (and not null), then we can return true immediately.
 Otherwise, we call array_key_exists() to see if the key is actually null.

 Technically slower for null or not-at-all-set keys, but faster when the
 key is set. And it is only slower by a simple isset(), which is fast.

 End result:
 {{{
 isset( $this->cache[ $group ] )
     && ( isset( $this->cache[ $group ][ $key ] )
         || array_key_exists( $key, $this->cache[ $group ] ) );
 }}}

 array_key_exists() went from being called all 2500 times, to only 192
 times, and the time cost of _exists() goes from 93ms to 9ms. Total time
 spent in cache.php falls by a third.

-- 
Ticket URL: <http://core.trac.wordpress.org/ticket/21320>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list