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.
I'm trying to optimize performance using Xdebug & Webgrind
OK, since you're in a position of seriously needing better performance, you might be open to a less than popular, but demonstrably effective, way to do it.
It works with any language, as long as there's a debugger that can be paused, like Xdebug.
Here it is described in a nutshell. Here's one demonstration of its effectiveness. I can link you many more.
You might find it a little intellectually wrenching. As in
You're finding "bottlenecks" as times associated with routines. The most valuable speedup opportunities often do not manifest that way. They are activities that you could easily describe when you see them, but they are diffuse. They do not concentrate significant time in any particular routine or line of code, so profilers don't see them.
The biggest speedup opportunities may not be at all easy to fix. They may require a re-think of how the program is organized. If you find something you can easily fix, that's great. Go ahead and do it. If it is not so easily fixed, but will still save a lot of time, if you need to save that time, then you've gotta do it, like it or not.
Good luck.
I don't like what hakre is suggesting. First off I would look if I can drop the Webserver. If so a good alternative is nginx or lighttpd. Compared to the Apache they are from this century and also the configuration is a lot easier. About the autoloading I don't really know but if the class files a really big did you tried to install a ram disk or use a php compressor? In my experience a PHP compressor can significantly fasten the execution time (i.e. parsing time).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With