PHP Preloading and Performance Impact
PHP Preloading performance impact explained, and demonstrated.
PHP Preloading is a mechanism that enables any application to /warm-up/ a collection of files by pre-compiling them, and keeping the generated byte code in memory. This feature, which has been introduced in PHP 7.4, is part of OPCache extension and provides a non-negligible performance boost, like Fabien mentioned recently on Symfony Blog.
“You cannot optimize what you cannot measure” is one of our mottos, which in this context could be slightly adapted to “In terms of performance, you cannot affirm what you cannot measure“. So let’s check the benefits of preloading with Blackfire Profiler.
The Application and Tools
For this performance test, I set up a simple Symfony 5.1 Demo application. Symfony indeed introduced a very nice improvement related to the PHP Preloading mechanism in the Dependency Injection component, dumping a preloading file into the cache directory of your application.
The test application has been deployed on SymfonyCloud, with Blackfire enabled:
name: blackfire-playground type: 'php:7.4' runtime: extensions: - apcu - blackfire - opcache
The application is accessible here: https://jszflcqa5e-a5i4gffd76b7w.eu.s5y.io/
Furthermore, in order to activate preloading, I added the following setting in the php.ini
file:
; as of 4.4.14 or 5.1.6 opcache.preload=/app/src/preload.php ; on Symfony 5.1+ before 5.1.6 opcache.preload=/app/var/cache/prod/App_KernelProdContainer.preload.php ; for Symfony 4.4 before 4.4.14 opcache.preload=/app/var/cache/prod/srcApp_KernelProdContainer.preload.php
The Result
The difference is significant, as the comparison graph shows it (the whole graph is accessible here):
Let’s analyze the before/after profiles:
Without Preloading
With Preloading
The 2 profiles have significant differences and emphasize interesting points:
- Preloading reduces the impact of class autoloading.
Indeed, even when optimizing Composer autoload, e.g. by dumping a classmap, autoloading usually remains an important bottleneck. Preloading clearly reduces the pressure of this fundamental mechanism, lowering the number of calls toComposer\Autoload\includeFile
(from 626 to 162) and toComposer\Autoload\ClassLoader::loadClass
(from 676 to 170). - Calls to the
App_KernelProdContainer::load
are 3 times less intense with preloading than without, when it comes to exclusive cost.
Conclusion
This little experiment demonstrated that preloading significantly reduced the noise induced by important tools our app relies on. This gives us a chance to focus even more on the behavior of our application, and this is an important step forward!
Play with the demo or subscribe now!
Happy Profiling!