Yii 1.1: Caching the config main.php

14 followers

Introduction:

The config long array included every time, and it's not cached at all!

The config first required In CApplication constructor

CApplication::__construct

just like this

public function __construct($config=null)
{
    Yii::setApplication($this);
 
    // set basePath at early as possible to avoid trouble
    if(is_string($config))
        $config=require($config);
//...

No caching goes here at all! even if you set it in main.php... At that point main.php event not loaded!

So if you want to cache it for some reason into memory for example, you can!

You will learn:

  • igbinary extension
  • Zend Data Cache (the same like xcache or apc)
  • The long way from app -> run, to the construction

Lets do it!

For this little tutorial I will use Zend Data Cache And igbinary for serialization

just open framework/base/CApplication.php see line 117 for __construct, and replace

if(is_string($config))
        $config=require($config);

With:

if(is_string($config)){     
if(($_config = igbinary_unserialize(zend_shm_cache_fetch("Yii::configs"))) === NULL)
{
zend_shm_cache_store("Yii::configs", igbinary_serialize(require($config)), 6000);
$config = igbinary_unserialize(zend_shm_cache_fetch("Yii::configs"));
}
else
{
    $config = $_config;
}
}

A little explanation:

if cache is NULL

if(($_config = igbinary_unserialize(zend_shm_cache_fetch("Yii::configs"))) === NULL)

this means it don't exists, or expired, so we will require the config array and cache it.

zend_shm_cache_store("Yii::configs", igbinary_serialize(require($config)), 6000);
$config = igbinary_unserialize(zend_shm_cache_fetch("Yii::configs"));

if the cache still exists and valid, we just read it.

That's it ...

It won't save you a lot of time, but with very big config, it could improve performance a little bit

You might think that the config array already cached if you turn on APC or Xcache etc.

Lets for learning purpose see all the path to CApplication::__construct

In your index.php you have

Yii::createWebApplication($config)->run();

Yii extends YiiBase

And have nothing inside

require(dirname(__FILE__).'/YiiBase.php');
class Yii extends YiiBase
{
}

Thats it...

Yii base have createWebApplication method

public static function createWebApplication($config=null)
    {
        return self::createApplication('CWebApplication',$config);
    }

lets see createApplication

public static function createApplication($class,$config=null)
    {
        return new $class($config);
    }

$class equals CWebApplication

CWebApplication constructor is extended from CApplication

And there you have

public function __construct($config=null)
    {
        Yii::setApplication($this);
 
        if(is_string($config)){
            $config = require($config);//no cache here ;-)
        }

Is it worth to do?

I did a test...

Like this:

$start = array_sum(explode(' ', microtime()));
//...
$end =  array_sum(explode(' ', microtime()));
        $result = $end - $start;
        echo $result;

When using Zend Optimizer+, there is about 0.00005 advantage to simple require (this is of course the array cached to memory automaticly by optimizer+, so you just waste the time with igbinary and cache it again etc.)

If you don't use it, the memory cache work 30 times faster than simple require

simple require takes about 0.003 sec. while my way takes about

0.0001 sec.

So my way works 30 times faster, or with no difference if op code cache used.

so I would say it worth it if you don't use some good op code cache...

Links

igbinary

zend data cache

Additional info

I'm sure most of you dont have Zend Data Cache or Zend Server...

You can use apc or xcache, it is all the same...

And for realization you can use serialize/unserialize instead of igbinary_serialize etc.

Total 11 comments

#15547 report it
Ferry Lukito at 2013/11/20 10:18am
hope include it in next yii version

I hope this will be added to next yii version. because change the file framework

at least this is very good for improve performance

#5132 report it
dckurushin at 2011/09/17 09:46am
response to luisloboborobia:

I used Zend Data Cache and igbinary, but you free to use whatever you want... You can replace igbinary with php default serialization. and instead of Zend Data Cache, you have apc, xcache, memcache etc.


I can't use Yii cache cause you define it in main.php, and that is what I cache...

And it is not worth it to define it manually twice...

#5131 report it
Luis Lobo Borobia at 2011/09/17 09:34am
Does it make any difference if using Yii's file cache?

Have you tried replacing zend and igserialize with Yii's file cache? That way we would not need any external component. Thanks!

#5112 report it
dckurushin at 2011/09/15 03:03am
A little improvment would be:

if replace

zend_shm_cache_store("Yii::configs", igbinary_serialize(require($config)), 6000);
$config = igbinary_unserialize(zend_shm_cache_fetch("Yii::configs"));

with

$config = require($config);
zend_shm_cache_store("Yii::configs", igbinary_serialize($config), 6000);

But it is matters only on the cache creation stage...

#5111 report it
Bravoman at 2011/09/15 02:57am
Nice

Seems like micro optimization to me. But I like it ;)

#5099 report it
dckurushin at 2011/09/14 11:55am
response to samdark:

I did a test...

Like this:

$start = array_sum(explode(' ', microtime()));
//...
$end =  array_sum(explode(' ', microtime()));
        $result = $end - $start;
        echo $result;

When using Zend Optimizer+, there is about 0.00005 advantage to simple require (this is of course the array cached to memory automaticly by optimizer+, so you just waste the time with igbinary and cache it again etc.)

If you don't use it, the memory cache work 30 times faster than simple require

simple require takes about 0.003 sec. while my way takes about

0.0001 sec.

So my way works 30 times faster, or with no difference if op code cache used.

so I would say it worth it if you don't use some good op code cache...

#5097 report it
samdark at 2011/09/14 11:35am
What to test

Overall application execution time w/ and w/o config cache to know if it's worth doing or not.

#5096 report it
dckurushin at 2011/09/14 09:48am
response to samdark:

I'm not sure what exactly to test here...

The time the include takes, and the reading from memory?

we save disk reading... but not much time...

#5095 report it
samdark at 2011/09/14 09:41am
Benchmarks?

Any benchmarks?

#5090 report it
dckurushin at 2011/09/14 05:17am
response to Volli: Turn on APC and it is cached automatically

Of course scripts will benefit from the caching, but this is not the same as caching the array in the memory.

#5088 report it
Volli at 2011/09/14 04:51am
APC

Turn on APC and it is cached automatically

Leave a comment

Please to leave your comment.

Write new article