So, I have been playing around with an idea in my head for a while, a few years now. It really came along as we started seeing more and more PHP applications rely on bootstrapping. For me it was as I saw more ZF applications becoming more and more complicated. At the time I was consulting and I would see significant server resources consumed by bootstrapping the apps. Loading config files, loading dependent classes, setting up dependencies, initializing ACL’s, and the list goes on and on.
One of the ways to negate the effect would be to cache a bootstrap object and then pull that object from the cache at the start of the request. However, the problem is that unserialization can actually end up taking more time than the bootstrap process itself.
So, I was wondering. Perhaps there would be a way to provide a cacheable state of the Zend Engine.
Perhaps it would look something like this.
init_engine_state(Callback $init);
What this would do is call the callback and after the callback returns, but before init_engine_state() returns, the engine would take a snapshot of everything except the superglobals. This would include classes, objects and opcodes. The next time a request comes in the callback would not be executed, but the state of the engine would be set to the state that it was in during the previous run of the callback.
Internally, what would happen before init_engine_state() returns is that all of the pertinent hash tables would be copied to a different memory block for the initial request. Then the next time a request comes in, memory for the copied hashtables would overwrite the existing ones. As noted earlier this could also include opcodes for files which would mean that the reams of autoloading function calls that typically happen could be completely bypassed.
I have seen legitimate cases where bootstrapping is taking 50% of the wallclock time. Perhaps by providing an engine hook like this PHP performance could be dramatically improved.
… or maybe I’m just speaking out of my buttocks.
Please comment. (On the idea, not my buttocks)
[UPDATE]
Here is an additional snippet of code that might help explain what I’m thinking of
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php $app = init_engine_state(function() { // This code would only be executed once require_once 'lib/code/Application.php'; require_once 'lib/code/Autolaoder.php'; $app = new Application(); $app->createAutoloader(); $app->bootstrap(); return $app; /* * At this point a snapshot would be taken of * - opcodes * - class definitions * - objects * */ }); // No autoloading would need to be done $adapter = Application::getAdapter(); $app->dispatch(); |
