Performance optimization ideas for PHP 7.3

php.internals

Nicolas Grekas

8 years ago
Hello internals, During the last months, I've been working on optimizing Symfony/Twig for PHP7. I found a few situations where the PHP engine could likely be optimized, and where it would benefit real-world apps. In each case, these might look like micro-optimizations, but they are not in hot loops. Here are the links to issues I created in the php bug tracker: - Class constants are slow: they should be inlined at runtime - https://bugs.php.net/76178 - Add array_key_exists() to the list of specialy compiled functions - https://bugs.php.net/76148 - Don't trigger copy-on-write when assigning same value - https://bugs.php.net/76150 As a bonus, I also created this one today: - Add hrtime() to zend_try_compile_special_func() - https://bugs.php.net/76241 It would be awesome if those ideas could be implemented in a future PHP version. (I'm sorry I don't have the knowledge to do it myself.) Keep up the good work! Nicolas

Albert Casademont Filella

8 years ago
Hi Nicolas, Don’t you think the biggest performance upgrade that PHP could bring is a real application server that could keep the app bootsrapped between requests, much like php-pm/reactphp/aerys are trying to do? Best, Albert On Thu, 19 Apr 2018 at 16:11, Nicolas Grekas <nicolas.grekas+php@gmail.com> wrote:

Marco Pivetta

8 years ago
On Thu, Apr 19, 2018 at 4:41 PM, Albert Casademont < albertcasademont@gmail.com> wrote:
> Hi Nicolas, > > Don’t you think the biggest performance upgrade that PHP could bring is a > real application server that could keep the app bootsrapped between > requests, much like php-pm/reactphp/aerys are trying to do? > > Best, > > Albert > >
There's enough userland doing that right now, and it already proves to be LUDICROUSLY FAST, so having it in core is probably not necessary right now. I'd rather say that the community is not yet ready for that anyway, as we lack widespread tooling to properly verify and isolate memory leaks in userland, and many libraries still heavily rely on statics for things that shouldn't be static (yikes!). Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/

Maxime Veber

8 years ago
Hello, Thank you very much Nicolas for theses detections ! (I'll try maybe my first contributions to PHP 😇) Albert, I think what you are speaking about is another topic. But still interesting. You should maybe try to use php pm and see how it works and what are the drawbacks to fix so it works nicely. (because they are many as I understood by reading the code of php-pm) Also Ocramius is right on the problem of memory leaks to fix in libraries, this is something to focus on. Another thread would be great (with more ideas to improve the situation). Maxime Le jeu. 19 avr. 2018 à 16:41, Albert Casademont <albertcasademont@gmail.com> a écrit :

Albert Casademont Filella

8 years ago
I agree on maybe opening another thread, I'm a contributor to PHP-PM so yes, we're trying to make things better on that end ;) On Thu, Apr 19, 2018 at 4:50 PM, Maxime Veber <nek.dev@gmail.com> wrote:

Nikita Popov

8 years ago
On Thu, Apr 19, 2018 at 4:10 PM, Nicolas Grekas < nicolas.grekas+php@gmail.com> wrote:
> Hello internals, > > During the last months, I've been working on optimizing Symfony/Twig for > PHP7. > I found a few situations where the PHP engine could likely be optimized, > and where it would benefit real-world apps. > > In each case, these might look like micro-optimizations, but they are not > in hot loops. > Here are the links to issues I created in the php bug tracker: > > - Class constants are slow: they should be inlined at runtime - > https://bugs.php.net/76178
This should in principle be straightforward. We just need to add a runtime cache for the constant lookup (or more generally, the constexpr AST evaluation). Possible complications: * The responsible opcode ZEND_RECV_INIT already uses a runtime cache slot for the class typehint, so there might be a bit of juggling involved in the runtime cache allocation. It might be easiest to always allocate the class name cache slot if the default value cache slot is used, even if it's not necessary, to avoid making this too complicated. * Some thought needs to be put into whether this is really valid in all cases. Apart from the things we already ignore in other runtime caches (value of a constant might change due to NS fallback), there are other cases to consider, such as `function($foo = "" . M_PI)`. The output could change at runtime based on the LC_NUMERIC locale and the precision ini setting, so the default value might change between calls. However, we already ignore this issue during compile-time evaluation, so I wouldn't consider this to be particularly problematic.
> - Add array_key_exists() to the list of specialy compiled functions - > https://bugs.php.net/76148 >
This is also straightforward. This will have to be a new opcode, because the key behavior is subtly different (e.g. for floating point keys) than in isset(). (And isset has all kinds of special handling not relevant to this.)
> - Don't trigger copy-on-write when assigning same value - > https://bugs.php.net/76150 >
This one on the other hand would be a major change, and I'm not sure it's a beneficial one (on average). It might give a large improvement for the specific, rare case discussed in the bug report, but will be a minor regression (on a very common operation) for everything else.
> As a bonus, I also created this one today: > - Add hrtime() to zend_try_compile_special_func() - > https://bugs.php.net/76241 > > It would be awesome if those ideas could be implemented in a future PHP > version. > (I'm sorry I don't have the knowledge to do it myself.) > > Keep up the good work!
If someone wants to try their hand implementing the 1st or 2nd optimization, feel free to ping me for some pointers. Nikita