PHP Preloading and Performance Impact

By Jérôme Vieilledent, on Sep 08, 2020

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):

Comparison of profiles, without and with PHP preloading enabled.

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 to Composer\Autoload\includeFile (from 626 to 162) and to Composer\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!

Jérôme Vieilledent

As a Developer Advocate, Jérôme is all about spreading the love! His technical/development background enable him to talk as a peer to peers with our developer users. You’ll read his tips and advices on performance management with Blackfire. And he’ll support you as a day-to-day user.