なぜPHPのautoload()が早いのか

__autoload()が早いというよりも、class_exists()に比べてrequre_once()、include_once()が遅いからというもの(クラスの読み込み判定の場合)。

通常__autoload()内でクラスの有無を調べて無ければ読み込みを行う。一度しか呼ばれないものならその場で読み込んだほうが早いが、複数回読み込み判定がおこなわれるものがある場合(Superクラスなど)一度autoload経由でclass_exists()の篩いにかけた方が良い。

PHP5のフレームワークではほとんどautoload系の読み込み実装がなされている事からも、その差は結構大きいので不特定回数読み込まれるファイルが多数ある場合は注意。

以下の動作環境で最も単純なクラス( class Sample{} )を1000回読み込んでインスタンス生成した場合、class_exists()で見つからなければrequire()と、常にrequire_once()だと100倍以上差があった。

  • PHP 5.2.3
  • WindowsXP SP2
  • AMD Athlon™ 64 Processor 3500+ 1.79GHz
  • 2.00GB RAM

1000回require_once() – 0.450819秒

<?php
for ($i=0;$i<1000;$i++) {
    require_once('Sample.php');
    $sample = new Sample();
}
----------------------------------------------------
marker  time index            ex time         perct
----------------------------------------------------
Start   1193042528.49833500   -                0.00%
----------------------------------------------------
Stop    1193042528.94915400   0.450819       100.00%
----------------------------------------------------

999回class_exists(), 1回require() – 0.003704秒

<?php
for ($i=0;$i<1000;$i++) {
    if (!class_exists('Sample', false)) {
        require('Sample.php');
    }
    $sample = new Sample();
}
----------------------------------------------------
marker  time index            ex time         perct
----------------------------------------------------
Start   1193042740.50069500   -                0.00%
----------------------------------------------------
Stop    1193042740.50439900   0.003704       100.00%
----------------------------------------------------

require()よりinclude()の方が早いのでinclude()にすればもう少し差は縮まるものの、なぜPHPのautoload()が早いかというとautoloadをclass_existsな実装で書く事が多いからであり、autoloadの中で全てrequire_once()していたら別に早くないという事。

クラス名の_をディレクトリとするPEAR風構成のオートローダーならZend FrameworkのZend_Loderがすぐ導入できます(Zend_LoaderとZend_Exceptionの2つで)。

環境違うと全然違うよ、な状態なら教えてください。