by Kevin Schroeder | 11:13 am

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();

Comments

evrt

I would absolutely LOVE this feature. I completely agree with the reasoning. We as PHP developers always suffer from the fact that we need to completely initialize the application, handle the request, send the response, and break down the application again. I got this idea too when I started working on a large ZF1 application.
I imagine it’s not super easy though. You’d definitely not want to cache anything like $_SERVER, and the developer would also have to be more careful not making any ‘decisions’ based on these values.

Feb 19.2013 | 09:54 am

    kschroeder

    My thought would be to copy the superglobals to a backup variable and then overwrite them after the opcodes, objects and variables have been copied.

    Feb 19.2013 | 03:45 pm

janoszen

The idea itself is not bad, in fact I have written an experimental PHP daemon that listens on a FastCGI socket and serves requests much like your desired feature. The problem however, is memory consumption. PHP has memory leaks in the most peculiar places and writing memory-efficient / non-leaky code is extremely hard no small part due to the fact, that there are no memory usage debugging tools whatsoever in PHP. It could be done, it has been done as well, but it will never be mainstream because the beauty of PHP is that less educated coders can do “stuff” with it. If you want do this, why not try a language that has been inherently designed for this? Believe me, I’ve been down that road and it requires a lot more work than learning an other language.

Feb 19.2013 | 10:40 am

lukaszkujawa

I wouldn’t call it dumb. It’s actually quite hard to not have a similar idea while working with big PHP applications. Every request literally hundreds of files have to be included, tens of regular expressions are executed and configs have to be parsed (as you pointed out). It’s irritating. I would be great to have something like java servlet. Persisting state which you can clone on demand.

Feb 20.2013 | 03:49 am

mrclay_org

Though I’ve never used Lisp, Lisp images (http://stackoverflow.com/a/585784/3779) come to mind, and I remember hearing planning for Dart to have an an image-based bootstrap (but can’t find it anywhere so they may have abandoned the idea).
This will probably never happen in core, but I have a lot of hope for the development of codebase optimizers based on static and runtime analysis. Basically they could analyze app usage under normal conditions then completely “compile” the app to several runtimes optimized for the most common code paths: move frequently-used code into a single file, move lesser-used code to be lazyloaded as needed, split up classes based on usage stats, break OO code down into faster procedural/global code, implement a highly-optimized loading mechanism (that may be faster than SPL autoloading), serialize bootstrap state (you already had that idea), etc.
It would be worth investing some thought into designing a style of programming that lends itself to this level of restructuring.

Feb 22.2013 | 12:37 pm

    mrclay_org

    The key is the optimized runtimes would still be vanilla PHP apps, runnable anywhere.

    Feb 22.2013 | 12:39 pm

DenisRaguzov

PHPDaemon is exist.

Feb 25.2013 | 09:08 am

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.