Hello all,
I've been thinking about PHP optimization and distribution, and I would
like to hear some opinions on introducing a new feature for a future PHP
7 version. Here's the concept: allow PHP opcode to be both saved after
parsing a file, and to be loaded and executed, similar to the bcompiler
extension and the APC bin functions back in the day.
The advantages are clear: libraries and applications could be compiled
to opcode ahead of time so PHP wouldn't have to compile it again and
again (assuming you're not already using OPcache).
A new function could be provided to parse a PHP file, but instead of
executing it, the compiled opcode would be saved to a file. It might
part of the OPcache extension if it makes sense, and could be called
opcache_compile_to_file() or something.
Another option would be to add a command-line flag to the interpreter to
write compiled opcode instead of executing it after parsing.
Another part of the feature would be to enable the interpreter to
execute compiled opcode scripts directly. This would work for both
compiled scripts passed to the interpreter, and scripts loaded with
include
and require
. We would probably need to introduce a new file
extension to specify opcode files. I'd recommend *.phpo or *.phpc.
This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great success
in Python, mostly for distributing releases of software or deploying to
a server.
I'm not at this moment planning an RFC, but I'd like to gauge your
opinions and reactions first.
--
Stephen
This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great success in
Python, mostly for distributing releases of software or deploying to a
server.
Correct me if I'm wrong, but this should already be possible with OpCache
and its filesystem backend in PHP 7.0.
See http://talks.php.net/froscon15#/php7pcache1 and following for
details.
This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great
success in
Python, mostly for distributing releases of software or deploying to a
server.Correct me if I'm wrong, but this should already be possible with OpCache
and its filesystem backend in PHP 7.0.See http://talks.php.net/froscon15#/php7pcache1 and following for
details.
That's great! That's about halfway toward what I'm looking for. That
means that the engine is likely already capable of doing these things --
the next step is to be able to execute any given .php.bin file like in
that talk. The idea would be to be able to bypass the caching mentality
by executing an already compiled file, instead of checking if the
original .php file has a corresponding bin file in the cache
--
Stephen
This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great
success in
Python, mostly for distributing releases of software or deploying to a
server.Correct me if I'm wrong, but this should already be possible with OpCache
and its filesystem backend in PHP 7.0.See http://talks.php.net/froscon15#/php7pcache1 and following for
details.That's great! That's about halfway toward what I'm looking for. That means that the engine is likely already capable of doing these things -- the next step is to be able to execute any given .php.bin file like in that talk. The idea would be to be able to bypass the caching mentality by executing an already compiled file, instead of checking if the original .php file has a corresponding bin file in the cache
You could simply deploy both the .php and the .bin files to achieve this today.
-Rasmus
This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great
success in
Python, mostly for distributing releases of software or deploying to a
server.Correct me if I'm wrong, but this should already be possible with OpCache
and its filesystem backend in PHP 7.0.See http://talks.php.net/froscon15#/php7pcache1 and following for
details.That's great! That's about halfway toward what I'm looking for. That means that the engine is likely already capable of doing these things -- the next step is to be able to execute any given .php.bin file like in that talk. The idea would be to be able to bypass the caching mentality by executing an already compiled file, instead of checking if the original .php file has a corresponding bin file in the cache
You could simply deploy both the .php and the .bin files to achieve this today.
-Rasmus
Would the bin files not have to be placed in the special OPcache file
store location though? That seems sub-optimal.
I'm glad it's already possible though. Thanks for the tip.
--
Stephen
This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great
success in
Python, mostly for distributing releases of software or deploying to a
server.Correct me if I'm wrong, but this should already be possible with OpCache
and its filesystem backend in PHP 7.0.See http://talks.php.net/froscon15#/php7pcache1 and following for
details.That's great! That's about halfway toward what I'm looking for. That means that the engine is likely already capable of doing these things -- the next step is to be able to execute any given .php.bin file like in that talk. The idea would be to be able to bypass the caching mentality by executing an already compiled file, instead of checking if the original .php file has a corresponding bin file in the cache
You could simply deploy both the .php and the .bin files to achieve this today.
-Rasmus
Would the bin files not have to be placed in the special OPcache file store location though? That seems sub-optimal.
But that is just a matter of copying the .bin files into a configurable directory. However, as others have said, this is completely pointless. If you are worried about initial compile latency on initial requests after a deeply of new code then simply run a couple of warmup requests before flipping your symlink to the new code. Beyond that I can't picture what possible use this could be. Hiding source code? No chance, getting PHP code from bytecode is trivial.
-Rasmus
Beyond that I can't picture what possible use this could be.
I also think that the ability to have a .phpc and .php side by side
would be nice, but not for hiding the source code. It would be useful
especially for php-cgi and secondary for php-cli. In php-cgi case theres
people who still host multiple sites on a single server and use the
php-cgi method because it doesn't requires to have an always running
instance like with php-fpm.
Lets say you are hosting 100 sites on a single server, imho it would be
less resourceful to run php-cgi processes on demand than having more
than 100 fpm processes idling for requests. So in this scenario, having
the flexibility to load byte code for php-cgi process would be a nice
performance boost.
Beyond that I can't picture what possible use this could be.
I also think that the ability to have a .phpc and .php side by side
would be nice, but not for hiding the source code. It would be useful
especially for php-cgi and secondary for php-cli. In php-cgi case theres
people who still host multiple sites on a single server and use the
php-cgi method because it doesn't requires to have an always running
instance like with php-fpm.Lets say you are hosting 100 sites on a single server, imho it would be
less resourceful to run php-cgi processes on demand than having more
than 100 fpm processes idling for requests. So in this scenario, having
the flexibility to load byte code for php-cgi process would be a nice
performance boost.
But that is exactly what the file-based opcache does by itself. The only
speedup you achieve by trying to distribute the .bin files would be a
minor boost the first time a cli script is executed. All subsequent runs
of the script would hit the cache. The added complexity and potential
version conflicts of trying to distribute the .bin files doesn't seem
like it would be worth the trouble for such a minor one-time performance
benefit.
-Rasmus
But that is exactly what the file-based opcache does by itself. The only
speedup you achieve by trying to distribute the .bin files would be a
minor boost the first time a cli script is executed. All subsequent runs
of the script would hit the cache. The added complexity and potential
version conflicts of trying to distribute the .bin files doesn't seem
like it would be worth the trouble for such a minor one-time performance
benefit.-Rasmus
But as far as I know thats only possible with php-cli and not with
php-cgi, is it?
But that is exactly what the file-based opcache does by itself. The only
speedup you achieve by trying to distribute the .bin files would be a
minor boost the first time a cli script is executed. All subsequent runs
of the script would hit the cache. The added complexity and potential
version conflicts of trying to distribute the .bin files doesn't seem
like it would be worth the trouble for such a minor one-time performance
benefit.-Rasmus
But as far as I know thats only possible with php-cli and not with
php-cgi, is it?
There is nothing cli-specific about this feature, so yes, it works fine
with php-cgi. You can set opcache.file_cache_only if you like to not
even try to create a shm cache and only use the file-based one for your
php-cgi setup.
-Rasmus
Beyond that I can't picture what possible use this could be.
I also think that the ability to have a .phpc and .php side by side would be
nice, but not for hiding the source code. It would be useful especially for
php-cgi and secondary for php-cli. In php-cgi case theres people who still
host multiple sites on a single server and use the php-cgi method because it
doesn't requires to have an always running instance like with php-fpm.
Which OpCache's file-backend covers...
I've been thinking about PHP optimization and distribution, and I would like
to hear some opinions on introducing a new feature for a future PHP 7
version. Here's the concept: allow PHP opcode to be both saved after parsing
a file, and to be loaded and executed, similar to the bcompiler extension
and the APC bin functions back in the day.
Back up. What problem are you /actually/ trying to solve? OPCache
does a very good job of caching the result of compilations, and it's a
standard, bundled extension in common use. Is there a hit for that
first load? Yes, but webservers run a very long time, and a priming
step during deployment is more robust that pushing pre-compiled script
databases.
The advantages are clear: libraries and applications could be compiled to
opcode ahead of time so PHP wouldn't have to compile it again and again
(assuming you're not already using OPcache).
That's a REALLY strange assumption to make. Who runs a PHP site where
performance is any kind of concern, but doesn't use OPCache? Are
these hypothetical people going to fail at that, but succeed at adding
an additional step to their deployment process? That seems unlikely.
A new function could be provided to parse a PHP file, but instead of
executing it, the compiled opcode would be saved to a file. It might part of
the OPcache extension if it makes sense, and could be called
opcache_compile_to_file() or something.
I'm not inherently against this as a concept, but again I have to ask:
"What problem does this solve?" because it certainly creates a new
one.
Here's my guess: You want to be able to distribute a library or
application without giving your users source code.
Apart from being a very non-open thing to do, it's also pointless.
Disassembling an opcode stream to PHP source code is trivial. Many
folks have tried to "encrypt" such bundles, and they've all been
broken, because eventually PHP has to be able to see the bytecodes.
Or am I wrong, and there's a motivation I'm just not seeing?
-Sara
Hi Stephen,
Le 13/11/2015 22:35, Stephen Coakley a écrit :
Hello all,
I've been thinking about PHP optimization and distribution, and I
would like to hear some opinions on introducing a new feature for a
future PHP 7 version. Here's the concept: allow PHP opcode to be both
saved after parsing a file, and to be loaded and executed, similar to
the bcompiler extension and the APC bin functions back in the day.The advantages are clear: libraries and applications could be compiled
to opcode ahead of time so PHP wouldn't have to compile it again and
again (assuming you're not already using OPcache).A new function could be provided to parse a PHP file, but instead of
executing it, the compiled opcode would be saved to a file. It might
part of the OPcache extension if it makes sense, and could be called
opcache_compile_to_file() or something.Another option would be to add a command-line flag to the interpreter
to write compiled opcode instead of executing it after parsing.Another part of the feature would be to enable the interpreter to
execute compiled opcode scripts directly. This would work for both
compiled scripts passed to the interpreter, and scripts loaded with
include
andrequire
. We would probably need to introduce a new
file extension to specify opcode files. I'd recommend *.phpo or *.phpc.This is quite similar to Python's ability to execute Python scripts
compiled to bytecode as *.pyc files. The feature has seen great
success in Python, mostly for distributing releases of software or
deploying to a server.I'm not at this moment planning an RFC, but I'd like to gauge your
opinions and reactions first.
AFAIK, generated bytecodes are not compatible across PHP versions. It
may work for relatively similar versions and preferably in acscending
order (executor more recent than compiler) but nothing is guaranteed.
So, in practice, you cannot distribute pre-compiled code if you must
impose a specific PHP version to execute it.
Python chose to maintain a backwards compatibility between compiler and
executor. PHP chose to cache transient opcodes. It may seem weaker but,
IMO, this is a better approach because it allows a total freedom when
creating, deprecating, and managing opcodes. Working on the engine would
be much harder if we had to maintain BC on pre-compiled code.
In practice, distributing pre-compiled PHP scripts wouldn't have any
noticeable impact on performance because anyone whi cares about
performance will enable opcache first (which should even be enabled by
default, IMO). As Sara noticed, the only benefit would be obfuscation,
which probably deserves a more powerful and reliable mechanism.
Regards
François