From ed86964868d24301032114f24ae069c1cfef9fd8 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 29 May 2017 10:53:43 +0200 Subject: [PATCH 1/4] Improved the main performance article to make it more actionable --- performance.rst | 126 ++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/performance.rst b/performance.rst index 322a9729267..d8fdead644b 100644 --- a/performance.rst +++ b/performance.rst @@ -4,91 +4,94 @@ Performance =========== -Symfony is fast, right out of the box. Of course, if you really need speed, -there are many ways that you can make Symfony even faster. In this article, -you'll explore some of the ways to make your Symfony application even faster. +Symfony is fast, right out of the box. Of course, if you really need speed, the +following performance checklists show how to make your application even faster. -.. index:: - single: Performance; Byte code cache +Symfony Application Checklist +----------------------------- -Use a Byte Code Cache (e.g. OPcache) ------------------------------------- +... -The first thing that you should do to improve your performance is to use a -"byte code cache". These caches store the compiled PHP files to avoid having -to recompile them for every request. +Install APCu Polyfill if your server uses APC + If your production server still uses the legacy APC PHP extension instead of + OPcache, install the `APCu Polyfill component`_ in your application to enable + compatibility with `APCu PHP functions`_ and unlock support for advanced + Symfony features, such as the APCu Cache adapter. -There are a number of `byte code caches`_ available, some of which are open -source. As of PHP 5.5, PHP comes with `OPcache`_ built-in. For older versions, -the most widely used byte code cache is `APC`_. +Development Machine Checklist +----------------------------- -.. tip:: +... - If your server still uses the legacy APC PHP extension, install the - `APCu Polyfill component`_ in your application to enable compatibility with - `APCu PHP functions`_ and unlock support for advanced Symfony features, such - as the APCu Cache adapter. +Production Server Checklist +--------------------------- -Using a byte code cache really has no downside, and Symfony has been designed -to perform really well in this type of environment. +.. index:: + single: Performance; Byte code cache -Monitoring Source File Changes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Use the OPcache byte code cache + OPcache cache stores the compiled PHP files to avoid having to recompile + them for every request. There are other `byte code caches`_ available, but + as of PHP 5.5, PHP comes with `OPcache`_ built-in. For older versions, the + most widely used byte code cache is `APC`_. -Most byte code caches monitor the source files for changes. This ensures that if -the source of a file changes, the byte code is recompiled automatically. -This is really convenient, but it adds overhead. +Configure OPcache for maximum performance + The default OPcache configuration is not suited for Symfony application, so + it's recommended to change these settings as follows: -For this reason, some byte code caches offer an option to disable these checks. -For example, to disable these checks in APC, simply add ``apc.stat=0`` to your -``php.ini`` configuration. + .. code-block:: ini -When disabling these checks, it will be up to the server administrators to -ensure that the cache is cleared whenever any source files change. Otherwise, -the updates you've made in the application won't be seen. + ; php.ini + ; maximum memory that OPcache can use to store compiled PHP files + opcache.memory_consumption=256M -For the same reasons, the byte code cache must also be cleared when deploying -the application (for example by calling ``apc_clear_cache()`` PHP function when -using APC and ``opcache_reset()`` when using OPcache). + ; maximum number of files that can be stored in the cache + opcache.max_accelerated_files=20000 -.. note:: +Don't check PHP timestamps + In production servers, PHP files should never change, unless a new application + version is deployed. However, by default OPcache checks if cached files have + changed their contents since caching them. This check introduces some overhead + that can be avoided as follows: - In PHP, the CLI and the web processes don't share the same OPcache. This - means that you cannot clear the web server OPcache by executing some command - in your terminal. You either need to restart the web server or call the - ``apc_clear_cache()`` or ``opcache_reset()`` functions via the web server - (i.e. by having these in a script that you execute over the web). + .. code-block:: ini -Optimizing all the Files Used by Symfony -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ; php.ini -By default, PHP's OPcache saves up to 2,000 files in the byte code cache. This -number is too low for the typical Symfony application, so you should set a -higher limit with the `opcache.max_accelerated_files`_ configuration option: + ; after each deploy, call ``opcache_reset()`` or restart the web server + ; to empty the cache and regenerated the cached files. Otherwise you won't + ; see the updates made in the application + opcache.validate_timestamps=0 -.. code-block:: ini + .. note:: - ; php.ini - opcache.max_accelerated_files = 20000 + The OPcache is different for the web server and the command console. + You cannot clear the web server OPcache by executing some command + in your terminal. You either need to restart the web server or call the + ``opcache_reset()`` function via the web server (i.e. by having this in + a script that you execute over the web). Configure the PHP realpath Cache --------------------------------- + PHP uses an internal cache to store the result of transforming file paths to + their real and absolute file system paths. The default config of this cache + is not suited for applications such as Symfony, which open many PHP files. + It's recommended to change these settings as follows: + + .. code-block:: ini + + ; php.ini + ; maximum memory allocated to store the results + realpath_cache_size=4096K + + ; save the results for 10 minutes (600 seconds) + realpath_cache_ttl=600 + -PHP uses an internal cache to store the result of mapping file paths to their -real and absolute file system paths. This increases the performance for -applications like Symfony that open many PHP files, especially on Windows -systems. -By default, PHP sets a ``realpath_cache_size`` of ``16K`` which is too low for -Symfony. Consider updating this value at least to ``4096K``. In addition, cached -paths are only stored for ``120`` seconds by default. Consider updating this -value too using the ``realpath_cache_ttl`` option: +----- -.. code-block:: ini +.. TODO:: reword the rest of this article. - ; php.ini - realpath_cache_size=4096K - realpath_cache_ttl=600 .. index:: single: Performance; Autoloader @@ -207,7 +210,6 @@ Learn more .. _`byte code caches`: https://en.wikipedia.org/wiki/List_of_PHP_accelerators .. _`OPcache`: http://php.net/manual/en/book.opcache.php -.. _`opcache.max_accelerated_files`: http://php.net/manual/en/opcache.configuration.php#ini.opcache.max-accelerated-files .. _`APC`: http://php.net/manual/en/book.apc.php .. _`APCu Polyfill component`: https://github.com/symfony/polyfill-apcu .. _`APCu PHP functions`: http://php.net/manual/en/ref.apcu.php From 146d9f73905a9a5e0c9ae6fddeea6179d799e528 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 31 May 2017 11:46:25 +0200 Subject: [PATCH 2/4] Use another format for the checklist --- performance.rst | 142 ++++++++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/performance.rst b/performance.rst index d8fdead644b..bf225a7ca00 100644 --- a/performance.rst +++ b/performance.rst @@ -26,107 +26,122 @@ Development Machine Checklist Production Server Checklist --------------------------- +* :ref:`Use the OPcache byte code cache ` +* :ref:`Configure OPcache for maximum performance ` +* :ref:`Don't check PHP timestamps ` +* :ref:`Configure the PHP realpath Cache ` +* :ref:`Optimize Composer Autoloader ` + .. index:: single: Performance; Byte code cache +.. _performance-use-opcache: + Use the OPcache byte code cache - OPcache cache stores the compiled PHP files to avoid having to recompile - them for every request. There are other `byte code caches`_ available, but - as of PHP 5.5, PHP comes with `OPcache`_ built-in. For older versions, the - most widely used byte code cache is `APC`_. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +OPcache stores the compiled PHP files to avoid having to recompile them for +every request. There are some `byte code caches`_ available, but as of PHP +5.5, PHP comes with `OPcache`_ built-in. For older versions, the most widely +used byte code cache is `APC`_. + +.. _performance-configure-opcache: Configure OPcache for maximum performance - The default OPcache configuration is not suited for Symfony application, so - it's recommended to change these settings as follows: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - .. code-block:: ini +The default OPcache configuration is not suited for Symfony application, so +it's recommended to change these settings as follows: - ; php.ini - ; maximum memory that OPcache can use to store compiled PHP files - opcache.memory_consumption=256M +.. code-block:: ini - ; maximum number of files that can be stored in the cache - opcache.max_accelerated_files=20000 + ; php.ini + ; maximum memory that OPcache can use to store compiled PHP files + opcache.memory_consumption=256M -Don't check PHP timestamps - In production servers, PHP files should never change, unless a new application - version is deployed. However, by default OPcache checks if cached files have - changed their contents since caching them. This check introduces some overhead - that can be avoided as follows: + ; maximum number of files that can be stored in the cache + opcache.max_accelerated_files=20000 - .. code-block:: ini +.. _performance-dont-check-timestamps: - ; php.ini +Don't check PHP timestamps +~~~~~~~~~~~~~~~~~~~~~~~~~~ - ; after each deploy, call ``opcache_reset()`` or restart the web server - ; to empty the cache and regenerated the cached files. Otherwise you won't - ; see the updates made in the application - opcache.validate_timestamps=0 +In production servers, PHP files should never change, unless a new application +version is deployed. However, by default OPcache checks if cached files have +changed their contents since caching them. This check introduces some overhead +that can be avoided as follows: - .. note:: +.. code-block:: ini - The OPcache is different for the web server and the command console. - You cannot clear the web server OPcache by executing some command - in your terminal. You either need to restart the web server or call the - ``opcache_reset()`` function via the web server (i.e. by having this in - a script that you execute over the web). + ; php.ini -Configure the PHP realpath Cache - PHP uses an internal cache to store the result of transforming file paths to - their real and absolute file system paths. The default config of this cache - is not suited for applications such as Symfony, which open many PHP files. - It's recommended to change these settings as follows: + ; after each deploy, call `opcache_reset()` or restart the web server + ; to empty the cache and regenerate the cached files. Otherwise you won't + ; see the updates made in the application + opcache.validate_timestamps=0 - .. code-block:: ini +.. note:: - ; php.ini - ; maximum memory allocated to store the results - realpath_cache_size=4096K + The OPcache is different for the web server and the command console. + You cannot clear the web server OPcache by executing some command + in your terminal. You either need to restart the web server or call the + ``opcache_reset()`` function via the web server (i.e. by having this in + a script that you execute over the web). - ; save the results for 10 minutes (600 seconds) - realpath_cache_ttl=600 +.. _performance-configure-realpath-cache: +Configure the PHP realpath Cache +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When a relative path is transformed into its real and absolute path, PHP +caches the result to improve performance. The default config of this cache +is not suited for applications that open many PHP files, such as Symfony. +It's recommended to change these settings as follows: ------ +.. code-block:: ini -.. TODO:: reword the rest of this article. + ; php.ini + ; maximum memory allocated to store the results + realpath_cache_size=4096K + ; save the results for 10 minutes (600 seconds) + realpath_cache_ttl=600 .. index:: single: Performance; Autoloader -Use Composer's Class Map Functionality --------------------------------------- - -By default, the Symfony Standard Edition uses Composer's autoloader -in the `autoload.php`_ file. This autoloader is easy to use, as it will -automatically find any new classes that you've placed in the registered -directories. +.. _performance-optimize-composer-autoloader: -Unfortunately, this comes at a cost, as the loader iterates over all configured -namespaces to find a particular file, making ``file_exists()`` calls until it -finally finds the file it's looking for. +Optimize Composer Autoloader +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The simplest solution is to tell Composer to build an optimized "class map", +The class loader used while developing the application is optimized to find +new and changed classes. In production servers, PHP files should never change, +unless a new application version is deployed. That's why you can optimize +Composer's autoloader to scan the entire application once and build a "class map", which is a big array of the locations of all the classes and it's stored in ``vendor/composer/autoload_classmap.php``. -The class map can be generated from the command line, and might become part of -your deploy process: +Execute this command to generate the class map (and make it part of your +deployment process too): .. code-block:: bash $ composer dump-autoload --optimize --no-dev --classmap-authoritative -``--optimize`` - Dumps every PSR-0 and PSR-4 compatible class used in your application. -``--no-dev`` - Excludes the classes that are only needed in the development environment - (e.g. tests). -``--classmap-authoritative`` - Prevents Composer from scanning the file system for classes that are not - found in the class map. +* ``--optimize`` dumps every PSR-0 and PSR-4 compatible class used in your + application; +* ``--no-dev`` excludes the classes that are only needed in the development + environment (e.g. tests); +* ``--classmap-authoritative`` prevents Composer from scanning the file + system for classes that are not found in the class map. + + +----- + +.. TODO:: reword the rest of this article. + Caching the Autoloader with APC ------------------------------- @@ -213,5 +228,4 @@ Learn more .. _`APC`: http://php.net/manual/en/book.apc.php .. _`APCu Polyfill component`: https://github.com/symfony/polyfill-apcu .. _`APCu PHP functions`: http://php.net/manual/en/ref.apcu.php -.. _`autoload.php`: https://github.com/symfony/symfony-standard/blob/master/app/autoload.php .. _`bootstrap file`: https://github.com/sensiolabs/SensioDistributionBundle/blob/master/Composer/ScriptHandler.php From 693847c8d770add86684002982e87745e34ec592 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 18 Jun 2017 16:42:26 +0200 Subject: [PATCH 3/4] Finished the reorganization of the article --- performance.rst | 178 +++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 93 deletions(-) diff --git a/performance.rst b/performance.rst index bf225a7ca00..a3be05a779d 100644 --- a/performance.rst +++ b/performance.rst @@ -10,27 +10,99 @@ following performance checklists show how to make your application even faster. Symfony Application Checklist ----------------------------- -... +#. :ref:`Install APCu Polyfill if your server uses APC ` +#. :ref:`Enable APC Caching for the Autoloader ` +#. :ref:`Use Bootstrap Files ` + +.. _performance-install-apcu-polyfill: Install APCu Polyfill if your server uses APC - If your production server still uses the legacy APC PHP extension instead of - OPcache, install the `APCu Polyfill component`_ in your application to enable - compatibility with `APCu PHP functions`_ and unlock support for advanced - Symfony features, such as the APCu Cache adapter. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Development Machine Checklist ------------------------------ +If your production server still uses the legacy APC PHP extension instead of +OPcache, install the `APCu Polyfill component`_ in your application to enable +compatibility with `APCu PHP functions`_ and unlock support for advanced Symfony +features, such as the APCu Cache adapter. + +.. _performance-autoloader-apc-cache: + +Enable APC Caching for the Autoloader +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The class autoloading mechanism is one of the slowest parts in PHP applications +that make use of lots of classes, such as Symfony. A simple way to improve its +performance is to use the :class:`Symfony\\Component\\ClassLoader\\ApcClassLoader`, +which caches the location of each class after it's located the first time. + +To use it, adapt your front controller file to use this ``ApcClassLoader`` class:: + + // app.php + // ... + + $loader = require_once __DIR__.'/../app/bootstrap.php.cache'; + + // Change 'sf' by something unique to this app to prevent + // conflicts with other applications running in the same server + $loader = new ApcClassLoader('sf', $loader); + $loader->register(true); + + // ... + +For more details, see :doc:`/components/class_loader/cache_class_loader`. + +.. note:: + + When using the APC autoloader, if you add new classes, they will be found + automatically and everything will work the same as before (i.e. no + reason to "clear" the cache). However, if you change the location of a + particular namespace or prefix, you'll need to flush your APC cache. Otherwise, + the autoloader will still be looking at the old location for all classes + inside that namespace. + +.. index:: + single: Performance; Bootstrap files + +.. _performance-iuse-bootstrap-files: + +Use Bootstrap Files +~~~~~~~~~~~~~~~~~~~ + +The Symfony Standard Edition includes a script to generate a so-called +`bootstrap file`_, which is a large file containing the code of the most +commonly used classes. This saves a lot of IO operations because Symfony no +longer needs to look for and read those files. + +If you're using the Symfony Standard Edition, then you're probably already +using the bootstrap file. To be sure, open your front controller (usually +``app.php``) and check to make sure that the following line exists:: + + require_once __DIR__.'/../app/bootstrap.php.cache'; + +Note that there are two disadvantages when using a bootstrap file: + +* the file needs to be regenerated whenever any of the original sources change + (i.e. when you update the Symfony source or vendor libraries); + +* when debugging, one will need to place break points inside the bootstrap file. + +If you're using the Symfony Standard Edition, the bootstrap file is automatically +rebuilt after updating the vendor libraries via the ``composer install`` command. + +.. note:: -... + Even when using a byte code cache, performance will improve when using a + bootstrap file since there will be fewer files to monitor for changes. Of + course, if this feature is disabled in the byte code cache (e.g. + ``apc.stat=0`` in APC), there is no longer a reason to use a bootstrap file. Production Server Checklist --------------------------- -* :ref:`Use the OPcache byte code cache ` -* :ref:`Configure OPcache for maximum performance ` -* :ref:`Don't check PHP timestamps ` -* :ref:`Configure the PHP realpath Cache ` -* :ref:`Optimize Composer Autoloader ` +#. :ref:`Use the OPcache byte code cache ` +#. :ref:`Configure OPcache for maximum performance ` +#. :ref:`Don't check PHP timestamps ` +#. :ref:`Configure the PHP realpath Cache ` +#. :ref:`Optimize Composer Autoloader ` .. index:: single: Performance; Byte code cache @@ -137,86 +209,6 @@ deployment process too): * ``--classmap-authoritative`` prevents Composer from scanning the file system for classes that are not found in the class map. - ------ - -.. TODO:: reword the rest of this article. - - -Caching the Autoloader with APC -------------------------------- - -Another solution is to cache the location of each class after it's located -the first time. Symfony comes with a class - :class:`Symfony\\Component\\ClassLoader\\ApcClassLoader` - -that does exactly this. To use it, just adapt your front controller file. -If you're using the Standard Distribution, this code should already be available -as comments in this file:: - - // app.php - // ... - - $loader = require_once __DIR__.'/../app/bootstrap.php.cache'; - - // Use APC for autoloading to improve performance - // Change 'sf2' by the prefix you want in order - // to prevent key conflict with another application - /* - $loader = new ApcClassLoader('sf2', $loader); - $loader->register(true); - */ - - // ... - -For more details, see :doc:`/components/class_loader/cache_class_loader`. - -.. note:: - - When using the APC autoloader, if you add new classes, they will be found - automatically and everything will work the same as before (i.e. no - reason to "clear" the cache). However, if you change the location of a - particular namespace or prefix, you'll need to flush your APC cache. Otherwise, - the autoloader will still be looking at the old location for all classes - inside that namespace. - -.. index:: - single: Performance; Bootstrap files - -Use Bootstrap Files -------------------- - -To ensure optimal flexibility and code reuse, Symfony applications leverage -a variety of classes and 3rd party components. But loading all of these classes -from separate files on each request can result in some overhead. To reduce -this overhead, the Symfony Standard Edition provides a script to generate -a so-called `bootstrap file`_, consisting of multiple classes definitions -in a single file. By including this file (which contains a copy of many of -the core classes), Symfony no longer needs to include any of the source files -containing those classes. This will reduce disc IO quite a bit. - -If you're using the Symfony Standard Edition, then you're probably already -using the bootstrap file. To be sure, open your front controller (usually -``app.php``) and check to make sure that the following line exists:: - - require_once __DIR__.'/../app/bootstrap.php.cache'; - -Note that there are two disadvantages when using a bootstrap file: - -* the file needs to be regenerated whenever any of the original sources change - (i.e. when you update the Symfony source or vendor libraries); - -* when debugging, one will need to place break points inside the bootstrap file. - -If you're using the Symfony Standard Edition, the bootstrap file is automatically -rebuilt after updating the vendor libraries via the ``composer install`` command. - -Bootstrap Files and Byte Code Caches -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Even when using a byte code cache, performance will improve when using a bootstrap -file since there will be fewer files to monitor for changes. Of course, if this -feature is disabled in the byte code cache (e.g. ``apc.stat=0`` in APC), there -is no longer a reason to use a bootstrap file. - Learn more ---------- From 23942b7683ea4463867a299539bc5fbaafe64fb8 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 18 Jun 2017 16:50:45 +0200 Subject: [PATCH 4/4] Fixed a typo --- performance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/performance.rst b/performance.rst index a3be05a779d..acb37551d2e 100644 --- a/performance.rst +++ b/performance.rst @@ -62,7 +62,7 @@ For more details, see :doc:`/components/class_loader/cache_class_loader`. .. index:: single: Performance; Bootstrap files -.. _performance-iuse-bootstrap-files: +.. _performance-use-bootstrap-files: Use Bootstrap Files ~~~~~~~~~~~~~~~~~~~