I'm working on a project with Zend Framework 1.11, Doctrine 2, some Symfony 2 componenents and others tools & libraries.
I'm trying to optimize performance using Xdebug & Webgrind.
I've already found some bottlenecks like parsing Ini config, etc.. and cached that.
Now, I just realize that the autoloading is the most costly part of my application:
Opl\Autoloader\ApcLoader->loadClass 274 31.36 43.86
Zend_Loader_PluginLoader->load 150 4.80 12.29
Zend_Loader_Autoloader->getClassAutoloaders 278 1.42 1.91
Zend_Controller_Router_Route_Regex->_getMappedValues 291 1.29 1.35
Doctrine\ORM\UnitOfWork->createEntity 85 1.24 3.18
As you can see I'm not using the default Zend_Loader_Autoloader
, I'm using Opl
which is, as far I know, quicker than it, I'm using the classMapLoader
with an APC cache but it still a bit slows compared to rest of the application.
How could I optimize that?
I've around 250 classes loaded, and it looks that only ~40 are slow, others show 0,00 as "Total call cost" but others are increasing from 0,08 to 0,57 on the require call.
By the way, since using the Opl autoloader, it looks that on my production environnement APC only opcode cache the file which are "manually required" not the ones which are called by the autoloader.
If refactoring your code is not an option (drop Zend Framework, Drop Doctrine, Drop ...) I would first optimize in buying better hardware. That will automatically optimize your code, because the context of the code is just shifted (this is not exactly optimizing the code, as the code won't change).
If that is not an option consider to create yourself a build system that can pre-process your codebase and create a non-development version of it to cut the loading process. This requires the analysis which files are needed always and you compile them all into a loader-optimized format which could be single file and/or static class loader maps.
However it's known that Zend needs to load a lot into memory always. Even using a PHP cache like APC might already bring you something (consider to pre-compile with the earlier noted build script and optimize the parts highlighted by your metrics).
If your application structure allows it, there is another possibility, too: Keep your whole application in memory between requests. That can be done with a PHP webserver. That done, the code only needs to get loaded once the server starts and will never needed to load again. This only works with your own application if it supports multiple requests. A good encapsulated application especially with the request logic can be adopted quite easily for that. An existing solution is appserver-in-php. You will be amazed how much the speed increases compared to the benefits you already gained from APC.
Maybe this was helpful. Any additional, more concrete suggestions are hard to make as it's not possible to see your code in action nor to have detailed metrics on it. You've just passed a fragment on what's going behind the scenes so it's hard to tell you more concretely.