用 Zephir 幫 Yii2 提速,做好玩的

概念是這樣的,前篇寫到 Zephir 可以很快的搞出一個 php extension,而我挺喜歡用 YII Framework,目前對 YII2 有興趣,雖然 YII 不慢,但純 PHP 的 Framework 效能其實測出來的反應速度都不怎麼樣啦,於是我就想說能否把部分類別取代掉來提速。

因此我建立了一個專案叫 BoostYii,此專案只有實作了一個類別叫 Object,這個類別是和 YII2 的 Object 類別是等效的,但我只有實做一半功能,因為某些功能太複雜了我就放棄,而為了保持相容性,我也另外寫了個 BoostYiiLoader.php 會判斷是否有 boostyii extension,只要在 index.php 中載入這個 Loader 就行了,不用改任何 Code 或 Yii2 Core Framework 即可得到效能的提升。

安裝方法介紹

首先 OS 內要有 zephir,若您是 CentOS 用戶可以參考我寫的前篇來安裝,其他的可以參考官方網站的說明,然後用 git 下載專案回來用 zephir 編譯,命令如下

git clone https://github.com/pigochu/zephir-boost-yii.git
cd zephir-boost-yii/extension-src
zephir build

如果順利安裝成功,會看到

Compiling...
Installing...
Extension installed!
Don't forget to restart your web server

接著,要新增一行 extension=boostyii.so 於 php.ini 或 /etc/php.d 建立 z-boostyii.ini 自己加進去。

上述 z-boostyii.ini 的命名是因為這個 boostyii.so 不可以比 json.so 先載入,否則會發生錯誤,所以用個 “z-” 的前綴就行了。

然後可以下命令看看是否有載入

 php --re boostyii
Extension [ <persistent> extension #56 boostyii version 0.0.1 ] {

  - Classes [3] {
    Interface [ <internal:boostyii> interface boostyii\base\Arrayable ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [1] {
        Method [ <internal:boostyii> abstract public method toArray ] {
        }
      }
    }

如果有正常載入,你可以重新啟動 php-fpm 或 web server 就可以於 yii2 web 使用了。

使用方法介紹

將 php-src 這個文件夾複製到 YII2 的專案,並且你可以改變這個文件夾名稱,然後於 index.php 中 include BoostYiiLoader.php 即可,如下範例為預設的 index.php 然後加上一行而已 :

<?php

// 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');

require(__DIR__ . '/../vendor/autoload.php');

require(__DIR__ . '/../vendor/yiisoft/yii2/yii/Yii.php');
## 只要增加這行就可以提速了!! 會不會太屌了啊@@
require(__DIR__ . '/../boostyii/BoostYiiLoader.php');

$config = require(__DIR__ . '/../config/web.php');

$application = new yii\web\Application($config);
$application->run();

就是這麼簡單啦 !!

效能測試

我用上述的使用方法建立了 index-boost.php 來和預設的 index.php 比較效能,我的環境如下

  • OS : CentOS 6.5 64bit
  • PHP 5.4.24 with APC
  • CPU INTEL Core2 E6750

以 ab 測試數據如下

ab -c 10 -t 10 http://localhost/boostyii/index.php

Document Path:  /boostyii/index.php
Document Length:11208 bytes

Concurrency Level:  10
Time taken for tests:   10.000 seconds
Complete requests:  2336
Failed requests:0
Write errors:   0
Total transferred:  27447386 bytes
HTML transferred:   26190080 bytes
Requests per second:233.60 [#/sec] (mean)
Time per request:   42.809 [ms] (mean)
Time per request:   4.281 [ms] (mean, across all concurrent requests)
Transfer rate:  2680.37 [Kbytes/sec] received

ab -c 10 -t 10 http://localhost/boostyii/index-boost.php

Document Path:  /boostyii/index-boost.php
Document Length:11244 bytes

Concurrency Level:  10
Time taken for tests:   10.002 seconds
Complete requests:  2545
Failed requests:0
Write errors:   0
Total transferred:  29993920 bytes
HTML transferred:   28624172 bytes
Requests per second:254.44 [#/sec] (mean)
Time per request:   39.302 [ms] (mean)
Time per request:   3.930 [ms] (mean, across all concurrent requests)
Transfer rate:  2928.40 [Kbytes/sec] received

這太扯了,竟然有 9% 的速度提升啊,我才去實作半個 Object 就有如此的效能改善,zephir 真是神器啊。

結語

採用上述方法提速所增加的一行 Code 其實拿去到沒有安裝 boostyii extension 的機器也是可以跑的,因為 Loader 本身會判斷是否有該 extension 然後才載入另外寫的 Object 類別,如果要更複雜些,用 spl_autoloader 來做 lazy loading 都行。

其實這個專案真的寫好玩的,我並不會真的繼續去發展 boostyii,只是要證明用我的方法,可以做到不影響相容性就可以提升 Yii2 的速度,相對的其他的純 PHP Framework 都可以如法炮製,只要先由最基底的類別去實作部分功能就行了。

發表迴響