Zend Framework パフォーマンス改善

お仕事で ZF アプリを作っていると、パフォーマンスも考えなくてはいけません。とりあえずこんな改善策をやってみました。

realpath キャッシュ

PHP 5.1 からは絶対パスを使うと realpath キャッシュというのが効いて、パフォーマンスが改善するようです。幸い、ZF のアプリでは、index.php が置いてある場所だけがわかれば、あとはそこから引けるので、以下のように値を設定しておきます。

define('APPLICATION_PATH', realpath(dirname(__FILE__)));

include_path 最適化

Zend Framework のパフォーマンスガイドにこうあります。

クラスの読み込み速度を上げるためにできる簡単な方法のひとつに、 include_path に気をつけるということがあります。特に大切なのは次の 4 つです。 絶対パス (あるいは絶対パスからの相対パス指定) を使うこと、 定義するインクルードパスの数を減らすこと、 Zend Framework の include_path をできるだけ早い段階で定義すること、 そしてカレントディレクトリは include_path の最後に指定することです。

index.php の先頭の方に以下のように書いておきます。現在は pear は使っておらず、ZF は library 以下にごそっと展開してあります。pear を使う方は、pearディレクトリを最後のほうに追加する必要があるでしょう。

define('APPLICATION_PATH', realpath(dirname(__FILE__)));
set_include_path(
    APPLICATION_PATH . '/../library' . PATH_SEPARATOR .
    APPLICATION_PATH . '/../application/controllers' . PATH_SEPARATOR .
    APPLICATION_PATH . '/../application/models'
);

テーブルのメタデータのキャッシュ

O/R マッパーを使っていると、DESCRIBE TABLE が頻繁に呼ばれます。データベースのプロファイルを取ると、結構な時間を無駄にしているので、これがなくなると結構パフォーマンスが上がります。

以下のようなコードを index.php に追加します。

// テーブルキャッシュの設定
$cache = Zend_Cache::factory('Core',
                             'File',
                             array('automatic_serialization' => true),
                             array('cache_dir' => APPLICATION_PATH . '/../cache'));
Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);

cache ディレクトリは、オーナーを apache にするか、777 にしておきます。

【蛇足】データベースのプロファイルを取る

データベース接続オプションに「'profiler' => true」を加えるだけで簡単にデータベースのプロファイルが取れます。

http://framework.zend.com/manual/ja/zend.db.profiler.html

id:wozozo の作ってくれたクエリー整形ツールを使って、時間がかかっているクエリーを見つけることができます。

http://blog.wozozo.jp/archives/111

【超基本】アプリケーションのパフォーマンスを測定する

apache bench を使うのが一般的です。アプリケーションサーバー以外から測定しないと参考になる値はとれません。

ab -n 1000 -c 10 http://hogehoge/

Requests per second: XX.XX [#/sec] (mean)

が、一秒間に何リクエストさばけるかを示します。当然大きいほうがパフォーマンスが上です。