PHPのautoloadはどこまで効率的なのかrequire_onceと比べてみた

autoloadのオーバーヘッドはどれぐらい?

モダンな実装のフレームワーク類には,かなりの割合で用意されているautoloadですが,require&require_once天国と比べてオーバーヘッドはどの程度変化しているのかと疑問に思って調べてみました.

不規則に何度も呼ばれる可能性があるばあいの,require_onceとの比較が中心です.

サンプル処理

いくつかの方法でクラスファイルを読み込むようにし,ダミーのインスタンスを1000回生成します.ぐるんぐるんです.

autoloadする

autoloadの処理がカラッポだとズルいので,適当なダミー処理を挟んでいます.

<?php
function autoload($className) {
    $chunks = explode('_', 'Dummy_Sample_Class_Name');
    $path   = implode('/', $chunks);
    if ( is_readable($path) ) {}

    require('./Class.php');
}
spl_autoload_register('autoload');

for ( $i=0; $i<1000; $i++ ) {
    $sample = new Class();
}
?>

毎度require_onceする

オートロードをしない場合の常套手段をシミュレートします.

<?php
for ( $i=0; $i<1000; $i++ ) {
    require_once('./php/Field.php');
    $sample = new Field();
}
?>

1度だけrequireする

ふつうに考えたら,これがいちばん速そうです.

<?php
require('./php/Field.php');
for ( $i=0; $i<1000; $i++ ) {
    $sample = new Field();
}
?>

リザルト

上記のサンプルコードを100回ずつ実行して,所要時間の平均(秒)を取りました.結果は以下のようになりました.

さくらのVPS 512MBプランのPHP5.3.6

autoloadの処理を100回平均(s)
float(0.0024403)
毎回require_onceの処理を100回平均(s)
float(0.0062124)
1度だけrequireの処理を100回平均(s)
float(0.0023656)

requireいちばんなのはもちろん,autoloadも十分速いです.クラス読み込みの判定は,ほとんどオーバーヘッドはなさそうです.

ローカルMAMPのphp5.2.11

autoloadの処理を100回平均(s)
float(0.0123375)
毎回require_onceの処理を100回平均(s)
float(0.0588991)
1度だけrequireの処理を100回平均(s)
float(0.0123648)

このMAMP環境は老朽化(?)で,全体的に動作トロいのですが,より差が開いています.ただし環境が違いすぎるのでPHPのバージョン違うが要因か,スペック要因かは不明です.

結論

検証の結果,require_onceのオーバーヘッドが思ったより小さくないことが分かりました.autoloadのほうが,実際のロジックによって変動するとはいえ,オーバーヘッドを低く抑えられています.

よって,今までrequire_onceを多用していたようなシーンでは,autoload実装に置き換えてしまったほうが,良いパフォーマンスを得ることもありそうです.もちろんautoloadが分厚かったらアレですが.

この検証は,1000回まわしたときの話なので,1回1回に希釈したら実際の影響はもっとちいさいでしょう.結局,ケースバイケースということで.

使われることが完全にわかりきっている分のクラスファイルは,オートロードのロジックを通さずにrequireするのがベストですよね