Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zend Config Ini Caching

My Zend app uses 3 ini config files, with a total of over 200 lines to parse, containing over 100 instructions. Are these files parsed every request? Some people say they are (like here and here). If so, is this not an efficiency issue?

The comments in those links have mixed sentiment - some say you should avoid ini config files and do your config in PHP, some say you could use Zend_Cache_Frontend_File, and some say it's just not an issue. But surely parsing 200 lines of text for every request will quickly become a problem if you are expecting quite a lot of traffic?

If you do recommend using a caching technique, can you please explain exactly how you would implement it?

like image 896
jackocnr Avatar asked Jul 27 '11 10:07

jackocnr


3 Answers

Yes, they are parsed every time unless you cache them. It really saves time (i checked it in my own project).

So how do you use Zend_Cache_Frontend_File to cache an ini file? Well I can provide you with an example. In my project I have route.ini file that contains a number of custom routes:

routes.ini

routes.showacc.route = "/@show/:city/:id/:type"
routes.showacc.type = "Zend_Controller_Router_Route" 
routes.showacc.defaults.module = default
routes.showacc.defaults.controller = accommodation
routes.showacc.defaults.action = show
routes.showacc.defaults.city = 
routes.showacc.defaults.type = 
routes.showacc.defaults.id = 
routes.showacc.defaults.title = 
routes.showacc.reqs.id = "\d+" 

;and more

In my Bootstrap.php I load them using cache (if possible):

protected function _initMyRoutes() {
    $this->bootstrap('frontcontroller');
    $front = Zend_Controller_Front::getInstance();
    $router = $front->getRouter();

    // get cache for config files
    $cacheManager = $this->bootstrap('cachemanager')->getResource('cachemanager');
    $cache = $cacheManager->getCache('configFiles');
    $cacheId = 'routesini';

    // $t1 = microtime(true);
    $myRoutes = $cache->load($cacheId);

    if (!$myRoutes) {
        // not in cache or route.ini was modified.
        $myRoutes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/routes.ini');
        $cache->save($myRoutes, $cacheId);
    }
    // $t2 = microtime(true);
    // echo ($t2-$t1); // just to check what is time for cache vs no-cache scenerio

    $router->addConfig($myRoutes, 'routes');
}

The cache is setup in my application.ini as follows

resources.cachemanager.configFiles.frontend.name = File
resources.cachemanager.configFiles.frontend.customFrontendNaming = false
resources.cachemanager.configFiles.frontend.options.lifetime = false
resources.cachemanager.configFiles.frontend.options.automatic_serialization = true
resources.cachemanager.configFiles.frontend.options.master_files[] = APPLICATION_PATH "/configs/routes.ini"    
resources.cachemanager.configFiles.backend.name = File
resources.cachemanager.configFiles.backend.customBackendNaming = false
resources.cachemanager.configFiles.backend.options.cache_dir = APPLICATION_PATH "/../cache"
resources.cachemanager.configFiles.frontendBackendAutoload = false

Hope this helps.

like image 100
Marcin Avatar answered Nov 19 '22 11:11

Marcin


If you load a framework like ZF you load dozens of files with thousands of lines of code. The files have to be read for each and every user and request. Server side you have some caching with disk controllers and whatnot so the files don't have to be actually read from disk each and every time. Also the memory managers in an operating system track it and provide some caching to the memory so this does not have to be read into memory every time--only out. Next you usually have a database where more or less the same thing happens because a database ultimately is stored in a file on a hard drive. The DB server reads the file and same story more or less.

So, would I worry about few lines in a config file? Certainly not because I need the data for my application to work. Where it is coming from is secondary.

About caching with Zend_Cache. If you have data which is compact and does not require a lot of processing like the files in Zend_Config you will gain save tiny microseconds. You are essentially storing a compact format into another compact format; serialized strings which have to be unserialized again. If you can cache data to avoid database access or rendering a whole view including all data requests with models kicking into gear we are talking about a whole different story.

like image 45
Adrian World Avatar answered Nov 19 '22 13:11

Adrian World


If you assume that PHP file is cached in memory vs parsed ini file which is also in memory you can get performance converting ini file to php file while skipping Zend_Config_Ini class and parsing process.

# public/index.php
$cachedConfigFile = APPLICATION_PATH.'/../cache/application.ini.'.APPLICATION_ENV.'.php';

if(!file_exists($cachedConfigFile) || filemtime($cachedConfigFile) < filemtime(APPLICATION_PATH . '/configs/application.ini'))
{
    require_once 'Zend/Config/Ini.php';
    $config = new Zend_Config_Ini( APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV );
    file_put_contents($cachedConfigFile, '<?php '.PHP_EOL.'return '.var_export($config->toArray(),true).';' );
}

$application = new Zend_Application(
    APPLICATION_ENV,
    $cachedConfigFile // originally was APPLICATION_PATH . '/configs/application.ini'
);

$application->bootstrap()
        ->run();

I'v tested with ab. Non cached config:

ab -n 100 -c 100 -t 10 http://localhost/
Requests per second:    45.57 [#/sec] (mean)
Time per request:       2194.574 [ms] (mean)
Time per request:       21.946 [ms] (mean, across all concurrent requests)
Transfer rate:          3374.08 [Kbytes/sec] received

vs Cached config:

Requests per second:    55.24 [#/sec] (mean)
time per request:       1810.245 [ms] (mean)
Time per request:       18.102 [ms] (mean, across all concurrent requests)
Transfer rate:          4036.00 [Kbytes/sec] received

That is 18% better performance.

like image 24
Collector Avatar answered Nov 19 '22 12:11

Collector