英文出处:Benchmarking Phalcon
距离上一次对比其他框架做基准测试已经有一段时间了。 实际上,我们最后一次在文档中的基准是Phalcon 1.3!抱歉,是我们的疏忽。
希望这篇文章能够在对Phalcon和您的应用程序期望值上向您提供一些视角。 毋庸置疑,每个应用程序都需要最好的设计,但是使用Phalcon可以进一步推动你的应用程序性能。
方式
我们已经为每一个框架安装了常备的应用。 我们相信有路由,控制器和视图去展示’hello’到显示器上。实际上这不是一个生动的例子,但是展示把字符串显示到屏幕上所需要加载的最小的资源。注意:每个框架提供了常见应用,我们要做的事是把每个框架部署到生产模式中去。
这次基准测试只能测量出每个框架启动,执行每一个action,显示结果,然后请求结束释放资源需要的时间。任何一个基于上述框架的PHP应用都需要时间和资源。可以假定任何比这个更复杂的实现每次请求将会消耗更多额外的资源。
这次测试将使用Apache的ab压力测试工具,1000个请求数5个并发数。
结果
我们开始我们的测试。在本次测试中我们为每个框架使用的硬件和配置都是相同的。
包含文件
我们使用get_included_files()函数来计算出每次请求包含了多少文件。这个函数在入口文件的结束位置调用,这个入口文件通常是index.php
。(越低越好)。
内存使用 (KB)
我们使用memory_get_usage()函数来计算出每次请求使用的内存。这个函数在入口文件的结束位置调用,这个入口文件通常是index.php
。(越低越好)。
每秒请求量 (平均值)
通过ab压测工具,我们测量出每个框架每秒能处理的请求量。(越高越好)。
完成一千次请求的时间
同样我们使用ab压测工具,我们测量出完成一千次请求所需要的时间。(越低越好)。
结论
在这次测试中可以看出Phalcon明显优于其他任何框架。
我们再次强调每个框架用的只是常用的应用。在你安装的基础上结果肯定不同。例如,开发人员可以从特定框架中删除服务,这将加速(至少包含的文件),但也可以添加更多的服务,这将减慢速度。没有什么比一个好的设计更好的了,但最好的设计也是为了应用程序服务的。但是,如果您可以通过使用Phalcon获得一些性能并降低内存消耗,那么如果您还没有这样做,这是值得一看的。
注意:如果我们的任何读者都有建议,我们可以实施,使这个基准尽可能现实,请随意在Github仓库发出请求提出您的建议
可以找到的最后一个基准测试是从2016年11月16日进行的TechEmpower。根据他们的测试时间表,我们应该在今年2月份看到第14轮,但还没有发生。
附录
Github仓库
硬件
我用Ubuntu Server 16.10设置了一个虚拟机。我们停止了X服务器,并分配了4GB的RAM和50GB的硬盘空间。
系统更新到最新的软件包后,Apache就安装在虚拟机上。对于PHP和Phalcon,我们选择使用来自OndřejSurý的PPA使用PHP 7.1。
PHP
版本
1 | PHP 7.1.3-3+deb.sury.org~yakkety+1 (cli) (built: Mar 25 2017 14:01:32) ( NTS ) |
模块
OPCache已启用,安装是默认的,没有在php.ini中进行任何修改。 安装的模块有:1
calendar, Core, ctype, curl, date, dom, exif, fileinfo, filter, ftp, gettext, hash, iconv, intl, json, libxml, mbstring, mcrypt, openssl, pcntl, pcre, PDO, phalcon, Phar, posix, readline, Reflection, session, shmop, SimpleXML, sockets , SPL, standard, sysvmsg, sysvsem, sysvshm, tokenizer, wddx, xml, xmlreader, xmlwriter, xsl, Zend OPcache, zlib
框架
比较的框架:
- FuelPHP (v1.8.0)
- Kohana (v3.3.6)
- Laravel (v5.4)
- Nette (v2.4)
- Phalcon (v3.1.2)
- Symfony (v3.2)
- Yii (v2.0.11)
- Zend Framework (v.3.0.1)
安装和更改
我们试图尽可能地实现这一测试,确保所有框架都以生产模式运行。 然而,没有人是完美的,所以任何建议,社区可以提供调整每个框架的最大潜力,随时在我们的Github仓库发出请求。FuelPHP
1
2curl https://get.fuelphp.com/oil | sh
oil create fuelphp
fuelphp/fuel/app/bootstrap.php1
2\Fuel::$env = \Arr::get($_SERVER, 'FUEL_ENV', \Arr::get($_ENV, 'FUEL_ENV', \Fuel::PRODUCTION));
// \Fuel::$env = \Arr::get($_SERVER, 'FUEL_ENV', \Arr::get($_ENV, 'FUEL_ENV', \Fuel::DEVELOPMENT));
fuelphp/fuel/app/views/welcome/index.php1
Hello World!
Kohana
1 | wget https://github.com/kohana/kohana/releases/download/v3.3.6/kohana-v3.3.6.zip |
kohana/application/bootstrap.php1
2
3
4
5if (isset($_SERVER['KOHANA_ENV']))
{
Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV']));
}
Kohana::$environment = Kohana::PRODUCTION;
kohana/application/classes/Controller/Welcome.php1
2
3
4
5
6
7
8
9
10
11
defined('SYSPATH') or die('No direct script access.');
class Controller_Welcome extends Controller_Template {
public $template = 'welcome';
public function action_index()
{
$this->template->message = 'Hello, World!';
}
} // End Welcome
kohana/application/views/welcome.php1
echo $message;
Laravel
1 | composer create-project --prefer-dist laravel/laravel laravel |
laravel/.env1
APP_DEBUG=false
laravel/config/app.php1
2
3
4...
'env' => env('APP_ENV', 'production'),
'debug' => env('APP_DEBUG', false),
...
laravel/resources/views/welcome.blade.php1
Hello World!
Nette
1 | composer create-project nette/web-project nette |
nette/app/presenters/templates/Homepage/default.latte1
Hello World!
Phalcon
Downloaded sample from the MVC repository.
phalcon/app/views/index.phtml1
Hello World!
Symfony
1 | composer create-project symfony/framework-standard-edition symfony |
symfony/app/Resources/views/base.html.twig1
Hello World
Yii
1 | composer global require "fxp/composer-asset-plugin:^1.2.0" |
yii/web/index.php1
2
3
4
5
// comment out the following two lines when deployed to production
//defined('YII_DEBUG') or define('YII_DEBUG', true);
//defined('YII_ENV') or define('YII_ENV', 'dev');
yii/config/web.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/**
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
*/
return $config;
yii/views/site/index.php1
Hello World!
yii/views/layouts/main.php1
= $content
Zend Framework
1 | composer create-project zendframework/skeleton-application zf |
zf/public/index.php1
2
3
4
5// Retrieve configuration
$appConfig = require __DIR__ . '/../config/application.config.php';
//if (file_exists(__DIR__ . '/../config/development.config.php')) {
// $appConfig = ArrayUtils::merge($appConfig, require __DIR__ . '/../config/development.config.php');
//}
zf/module/Application/view/layout/layout.phtml1
= $this->content
ab压测结果
FuelPHP
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
Kohana
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
Laravel
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
Nette
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
Phalcon
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
Symfony
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
Yii
1 | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |