性能

Symfony极其之快。当然了,如果你真正需要速度,还有许多能让你令Symfony变得更快的方法。本章,你将探索一些方法,来让Symfony程序快上加快。

使用Byte Code缓存(如OPcache) 

你应该做的第一件事

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.

使用byte code cache

监控源文件的改变 

多数byte code cache

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.

当关闭这些检查时,

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

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

优化全部Symfony使用的文件 

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:

1
2
; php.ini
opcache.max_accelerated_files = 20000

配置PHP realpath缓存 

PHP使用了一个内部缓存来存储

默认时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:

1
2
3
; php.ini
realpath_cache_size=4096K
realpath_cache_ttl=600

使用Composer的类映射功能 

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.

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.

The simplest solution is to tell Composer to build an optimized "class map", which is a big array of the locations of all the classes and it's stored in vendor/composer/autoload_classmap.php.

这个类映射

1
$  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.

用APC缓存Autoloader 

Another solution is to cache the location of each class after it's located the first time. Symfony comes with a class - ApcClassLoader - that does exactly this. To use it, just adapt your front controller file. If you're using the Standard Distribution, make the following changes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// app.php
// ...
 
use Symfony\Component\ClassLoader\ApcClassLoader;
 
$loader = require __DIR__.'/../app/autoload.php';
include_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 Cache a Class Loader.

当使用APC自动加载器时,

使用Bootstrap文件 

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.

如果你正在使用Symfony标准版,

1
include_once __DIR__.'/../var/bootstrap.php.cache';

注意当使用bootstrap文件时有两个不利点:

  • 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文件和Byte Code缓存 

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.

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)