# Proposal: Startup snapshot for optimizing app load time

- Thread: https://externals.io/message/92249
- Original archive: https://news-web.php.net/php.internals/92249
- Started by Lin Yo-An on 2016-04-13T15:55:49+00:00
- Messages: 8
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #92249 — Lin Yo-An — 2016-04-13T15:55:49+00:00

URL: https://externals.io/message/92249#92249

Hi internals,


The javascript engine V8 uses a strategy called "startup snapshot" to
optimize app load time (see
http://v8project.blogspot.tw/2015/09/custom-startup-snapshots.html for more
details)

The approach used by V8 creates a snapshot from heap, so the V8Context
could be reused directly without re-running the bootstraping code.

I think running javascript app in the browser is somehow like we run php
script for each requests where the app bootstrapping code is required to be
executed repeatedly for each request.

Currently, our opcache extension can cache the byte codes, but the byte
codes still need to be executed every time when bootstrapping an app, and
which increases the overhead for each request.

For example, a lot of applications use composer to initialize the class
loader via the statement below:

    require "vendor/autoload.php";

The statement above produces thousands of byte code to run, which is to
make an app ready. (If you use vld extension to show the opcodes)

However, if we can support a simple syntax to describe what is doing
"bootstrap", we are able to create a startup snapshot from it.


The proposal here want to introduce some new syntax to optimize app load
time though the below syntax:

    bootstrap "vendor/autoload.php";  // caches the context after running
this script.

Or

    bootstrap {
           require "vendor/autoload.php";
           // do something else for making app ready
    };

And of course, we might detect the bootstrap script automatically without
creating new syntax and opcodes, but I think it's hard to do because PHP
applications can be written by many ways...


Questions
========

I don't know if this approach is doable or not. Or maybe we can support
this in a separated extension instead of changing the zend core?

Do you guys think it's doable? would you like to share your idea for this?






Best Regards,

Yo-An Lin

---

## #92250 — Marco Pivetta — 2016-04-13T16:32:33+00:00

URL: https://externals.io/message/92249#92250 · In reply to: #92249

While this seems interesting, how would it address storing any context
information of extension?

The code above (in your examples) only stores information about the
autoload stack, but anything that would rely on any extension (core or pecl
or custom) would have to serialize information that is possibly not even
available in userland.

Any clue on that? Would it be acceptable to have it just fail/fatal?


Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/



> Hi internals,
>
>
> The javascript engine V8 uses a strategy called "startup snapshot" to
> optimize app load time (see
> http://v8project.blogspot.tw/2015/09/custom-startup-snapshots.html for
> more
> details)
>
> The approach used by V8 creates a snapshot from heap, so the V8Context
> could be reused directly without re-running the bootstraping code.
>
> I think running javascript app in the browser is somehow like we run php
> script for each requests where the app bootstrapping code is required to be
> executed repeatedly for each request.
>
> Currently, our opcache extension can cache the byte codes, but the byte
> codes still need to be executed every time when bootstrapping an app, and
> which increases the overhead for each request.
>
> For example, a lot of applications use composer to initialize the class
> loader via the statement below:
>
>     require "vendor/autoload.php";
>
> The statement above produces thousands of byte code to run, which is to
> make an app ready. (If you use vld extension to show the opcodes)
>
> However, if we can support a simple syntax to describe what is doing
> "bootstrap", we are able to create a startup snapshot from it.
>
>
> The proposal here want to introduce some new syntax to optimize app load
> time though the below syntax:
>
>     bootstrap "vendor/autoload.php";  // caches the context after running
> this script.
>
> Or
>
>     bootstrap {
>            require "vendor/autoload.php";
>            // do something else for making app ready
>     };
>
> And of course, we might detect the bootstrap script automatically without
> creating new syntax and opcodes, but I think it's hard to do because PHP
> applications can be written by many ways...
>
>
> Questions
> ========
>
> I don't know if this approach is doable or not. Or maybe we can support
> this in a separated extension instead of changing the zend core?
>
> Do you guys think it's doable? would you like to share your idea for this?
>
>
>
>
>
>
> Best Regards,
>
> Yo-An Lin

---

## #92251 — Larry Garfield — 2016-04-13T16:37:33+00:00

URL: https://externals.io/message/92249#92251 · In reply to: #92249

> Hi internals,
>
>
> The javascript engine V8 uses a strategy called "startup snapshot" to
> optimize app load time (see
> http://v8project.blogspot.tw/2015/09/custom-startup-snapshots.html for more
> details)
>
> The approach used by V8 creates a snapshot from heap, so the V8Context
> could be reused directly without re-running the bootstraping code.
>
> I think running javascript app in the browser is somehow like we run php
> script for each requests where the app bootstrapping code is required to be
> executed repeatedly for each request.
>
> Currently, our opcache extension can cache the byte codes, but the byte
> codes still need to be executed every time when bootstrapping an app, and
> which increases the overhead for each request.
>
> For example, a lot of applications use composer to initialize the class
> loader via the statement below:
>
>      require "vendor/autoload.php";
>
> The statement above produces thousands of byte code to run, which is to
> make an app ready. (If you use vld extension to show the opcodes)
>
> However, if we can support a simple syntax to describe what is doing
> "bootstrap", we are able to create a startup snapshot from it.
>
>
> The proposal here want to introduce some new syntax to optimize app load
> time though the below syntax:
>
>      bootstrap "vendor/autoload.php";  // caches the context after running
> this script.
>
> Or
>
>      bootstrap {
>             require "vendor/autoload.php";
>             // do something else for making app ready
>      };
>
> And of course, we might detect the bootstrap script automatically without
> creating new syntax and opcodes, but I think it's hard to do because PHP
> applications can be written by many ways...
>
>
> Questions
> ========
>
> I don't know if this approach is doable or not. Or maybe we can support
> this in a separated extension instead of changing the zend core?
>
> Do you guys think it's doable? would you like to share your idea for this?

I have no idea how feasible it is for the engine.  It may be impossible, 
or it may be straightforward.  However, if it can be done then it would 
allow for vastly improved architecture for large applications.  Many 
large systems (Drupal being the example I know best) spend a lot of time 
trying to optimize their bootstrap, loading as few services as possible, 
adding complexity and indirection to lazy-load services, etc. because 
that code is executed on every request.  That means even a single 
function call removed along that critical path can add up to a lot of 
time over the course of a day.  If instead we could snapshot a point in 
time and restart there, we could remove all of that optimization and 
make the bootstrap process actively load most of the system, then freeze 
it; then requests come in to a fully booted system and we save a ton of 
time initializing services on every request.  I'd love that.

The trick, of course, is that PHP's standard setup model assumes that 
the environment is created before the code is even loaded.  The 
superglobals, for instance, exist before the first line of userspace 
code, yet those are the things that will vary per run *after* the 
snapshot is made.  And then there's the question of how to detect and 
trigger a re-bootstrap, say when code is updated.  For that reason, I 
suspect such a change would require far more than just a few new 
keywords; there would need to be some sever-level specification of a 
bootstrap script that is distinct from the user-facing script that the 
web server executes, and a few thousand edge cases to think about.

-- 
--Larry Garfield

---

## #92426 — francois@php.net — 2016-04-18T19:10:37+00:00

URL: https://externals.io/message/92249#92426 · In reply to: #92249

Hi,

Le 13/04/2016 17:55, Lin Yo-An a écrit :
> Hi internals,
>
>
> The javascript engine V8 uses a strategy called "startup snapshot" to
> optimize app load time (see
> http://v8project.blogspot.tw/2015/09/custom-startup-snapshots.html for more
> details)
>
> The approach used by V8 creates a snapshot from heap, so the V8Context
> could be reused directly without re-running the bootstraping code.
>
> I think running javascript app in the browser is somehow like we run php
> script for each requests where the app bootstrapping code is required to be
> executed repeatedly for each request.
>
> Currently, our opcache extension can cache the byte codes, but the byte
> codes still need to be executed every time when bootstrapping an app, and
> which increases the overhead for each request.
>
> For example, a lot of applications use composer to initialize the class
> loader via the statement below:
>
>      require "vendor/autoload.php";
>
> The statement above produces thousands of byte code to run, which is to
> make an app ready. (If you use vld extension to show the opcodes)
>

You are mixing 2 related mechanisms here : code persistence and data 
persistence.

Code persistence (reloading the same code again and again in each 
request) is achieved through the autoloader. Autoloading, compbined with 
opcache provides a very fast mechanism to retrieve class definitions. If 
you measure the time taken by your 'require "vendor/autoload.php"' 
stance, you should find it to be extremely fast (with opcache on, of 
course).

Data persistence is another question: the need here is to save and 
restore object instances. Several cache mechanisms exist for this, 
saving and restoring via serialize/unserialize. The problem with your 
'bootstrap' approach (apart from the fact that it is not physically 
possible in PHP) is that you won't want to snapshot the *whole* 
environment, because you always want to keep at least some dynamic 
context. What you actually want to 'snapshot' is a set of well-defined 
object instances. So, the question, IMO, is to develop a mechanism 
faster than the current ones to store and retrieve object instances from 
memory.

Regards

François

---

## #92475 — David Zuelke — 2016-04-19T16:54:00+00:00

URL: https://externals.io/message/92249#92475 · In reply to: #92249

I think this solution is merely a band-aid for a more profound architectural weakness of current PHP setups, where a web server call out to the engine (via embedding or FastCGI) to execute a script, which causes this recurring initialization overhead in the first place.

The future is (or should be) servers implemented fully in PHP code (e.g. PHP-PM), just like every other comparable language (Ruby, Python, Java, ...) already does. That also brings many other benefits, such as the ability to handle upgrades to WebSockets in the same codebase, stream request bodies as they're being uploaded, and so forth.

And the performance figures that PHP-PM delivers with Symfony validate that approach IMO.


> 
> 
> Hi internals,
> 
> 
> The javascript engine V8 uses a strategy called "startup snapshot" to
> optimize app load time (see
> http://v8project.blogspot.tw/2015/09/custom-startup-snapshots.html for more
> details)
> 
> The approach used by V8 creates a snapshot from heap, so the V8Context
> could be reused directly without re-running the bootstraping code.
> 
> I think running javascript app in the browser is somehow like we run php
> script for each requests where the app bootstrapping code is required to be
> executed repeatedly for each request.
> 
> Currently, our opcache extension can cache the byte codes, but the byte
> codes still need to be executed every time when bootstrapping an app, and
> which increases the overhead for each request.
> 
> For example, a lot of applications use composer to initialize the class
> loader via the statement below:
> 
>    require "vendor/autoload.php";
> 
> The statement above produces thousands of byte code to run, which is to
> make an app ready. (If you use vld extension to show the opcodes)
> 
> However, if we can support a simple syntax to describe what is doing
> "bootstrap", we are able to create a startup snapshot from it.
> 
> 
> The proposal here want to introduce some new syntax to optimize app load
> time though the below syntax:
> 
>    bootstrap "vendor/autoload.php";  // caches the context after running
> this script.
> 
> Or
> 
>    bootstrap {
>           require "vendor/autoload.php";
>           // do something else for making app ready
>    };
> 
> And of course, we might detect the bootstrap script automatically without
> creating new syntax and opcodes, but I think it's hard to do because PHP
> applications can be written by many ways...
> 
> 
> Questions
> ========
> 
> I don't know if this approach is doable or not. Or maybe we can support
> this in a separated extension instead of changing the zend core?
> 
> Do you guys think it's doable? would you like to share your idea for this?
> 
> 
> 
> 
> 
> 
> Best Regards,
> 
> Yo-An Lin

---

## #92479 — Fleshgrinder — 2016-04-19T17:50:40+00:00

URL: https://externals.io/message/92249#92479 · In reply to: #92475

> I think this solution is merely a band-aid for a more profound architectural weakness of current PHP setups, where a web server call out to the engine (via embedding or FastCGI) to execute a script, which causes this recurring initialization overhead in the first place.
> 
> The future is (or should be) servers implemented fully in PHP code (e.g. PHP-PM), just like every other comparable language (Ruby, Python, Java, ...) already does. That also brings many other benefits, such as the ability to handle upgrades to WebSockets in the same codebase, stream request bodies as they're being uploaded, and so forth.
> 
> And the performance figures that PHP-PM delivers with Symfony validate that approach IMO.
> 

This requires proper memory management, no matter how:

https://software-gunslinger.tumblr.com/post/47131406821/php-is-meant-to-die

https://software-gunslinger.tumblr.com/post/48215406921/php-is-meant-to-die-continued

-- 
Richard "Fleshgrinder" Fussenegger

---

## #92482 — Dmitry Stogov — 2016-04-19T18:39:42+00:00

URL: https://externals.io/message/92249#92482 · In reply to: #92249

It should be possible to do this for functions and simple classes.
Most probably this will require some engine changes, but this is not a big problem for major release.
Conditional definition and run-time class inheritance will make significant troubles.

Thanks. Dmitry.
________________________________________
From: Lin Yo-An <cornelius.howl@gmail.com>
Sent: Wednesday, April 13, 2016 18:55
To: internals@lists.php.net
Subject: [PHP-DEV] Proposal: Startup snapshot for optimizing app load time

Hi internals,


The javascript engine V8 uses a strategy called "startup snapshot" to
optimize app load time (see
http://v8project.blogspot.tw/2015/09/custom-startup-snapshots.html for more
details)

The approach used by V8 creates a snapshot from heap, so the V8Context
could be reused directly without re-running the bootstraping code.

I think running javascript app in the browser is somehow like we run php
script for each requests where the app bootstrapping code is required to be
executed repeatedly for each request.

Currently, our opcache extension can cache the byte codes, but the byte
codes still need to be executed every time when bootstrapping an app, and
which increases the overhead for each request.

For example, a lot of applications use composer to initialize the class
loader via the statement below:

    require "vendor/autoload.php";

The statement above produces thousands of byte code to run, which is to
make an app ready. (If you use vld extension to show the opcodes)

However, if we can support a simple syntax to describe what is doing
"bootstrap", we are able to create a startup snapshot from it.


The proposal here want to introduce some new syntax to optimize app load
time though the below syntax:

    bootstrap "vendor/autoload.php";  // caches the context after running
this script.

Or

    bootstrap {
           require "vendor/autoload.php";
           // do something else for making app ready
    };

And of course, we might detect the bootstrap script automatically without
creating new syntax and opcodes, but I think it's hard to do because PHP
applications can be written by many ways...


Questions
========

I don't know if this approach is doable or not. Or maybe we can support
this in a separated extension instead of changing the zend core?

Do you guys think it's doable? would you like to share your idea for this?






Best Regards,

Yo-An Lin

---

## #92533 — S.A.N — 2016-04-20T10:43:34+00:00

URL: https://externals.io/message/92249#92533 · In reply to: #92475

2016-04-19 19:54 GMT+03:00 David Zuelke <dz@heroku.com>:
> I think this solution is merely a band-aid for a more profound architectural weakness of current PHP setups, where a web server call out to the engine (via embedding or FastCGI) to execute a script, which causes this recurring initialization overhead in the first place.
>
> The future is (or should be) servers implemented fully in PHP code (e.g. PHP-PM), just like every other comparable language (Ruby, Python, Java, ...) already does. That also brings many other benefits, such as the ability to handle upgrades to WebSockets in the same codebase, stream request bodies as they're being uploaded, and so forth.
>
> And the performance figures that PHP-PM delivers with Symfony validate that approach IMO.
>

I agree, and developers are already discussing a common event-loop API:
https://github.com/async-interop/event-loop
