include_path+__autoload與陣列+__autoload的比較
今天得知了一種不用include_path而選擇用陣列來快取類名來autoload的方法..
這種方法也比較巧妙..我們知道 include_path當設定的目錄很多的時候..遍歷是非常耗時的.
所以這種方法捨棄include_path..而是自己建立了一個數組..陣列的鍵名為類名..鍵值為此類對應的路徑.
下面是個簡單的例子
$classes = array( 'ClassA' => '/home/webroot/ClassA.class.php', 'ClassB' => '/home/webroot/ClassB.class.php', ); function __autoload($class) { global $classes; if(array_key_exists($class, $classes)) { //存在此類就去包含其路徑 require_once($classes[$class]); } }
但是這種方法又與include_path效率上有什麼區別呢?
我們來測試一下吧..
首先我在當前目錄下.用程式新建了6個資料夾 分別為a b c d e f
然後每個資料夾內又生成了1000個檔案 檔名的規則是這樣的 資料夾名+數字
比如資料夾a裡面有a0.php到a1000.php
裡面的內容就是一個空的類 類名和檔名一樣 比如a100.php 中的內容是
<?php class a100 {} ?>
目錄結構想必大家都明白了..
那麼現在我們開始寫程式碼..
先來測試include_path方法 下面是我的程式碼
<?php !defined('__DIR__') && define('__DIR__', dirname(__FILE__)); ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . __DIR__ . '/a/' . PATH_SEPARATOR . __DIR__ . '/b/' . PATH_SEPARATOR . __DIR__ . '/c/' . PATH_SEPARATOR . __DIR__ . '/d/' . PATH_SEPARATOR . __DIR__ . '/e/' . PATH_SEPARATOR . __DIR__ . '/f/' . PATH_SEPARATOR ); function __autoload($class) { require_once($class.'.php'); } $time=microtime(true); for($i=0;$i<=100;$i++) { $class = chr(rand(97, 102)) . rand(0, 1000); new $class(); } echo microtime(true)-$time;
這種方法在我的機器上執行的時間大概為0.21659898757935 左右
下面我們來測試第二種方法..第二種方法需要構造出一個數組..如果是專案來說一般都是手工配置的.在這裡我們就用程式生成吧..但是不算在autoload時間內..
<?php !defined('__DIR__') && define('__DIR__', dirname(__FILE__)); //構造出陣列 $classes = array(); for($chr=97;$chr<=102;$chr++) { $tmp = chr($chr); for($i=0;$i<=1000;$i++) { $classes[$tmp.$i] = __DIR__."/$tmp/{$tmp}{$i}.php"; } } function __autoload($class) { global $classes; if(array_key_exists($class, $classes)) { require_once($classes[$class]); } } $time=microtime(true); for($i=0;$i<=100;$i++) { $class = chr(rand(97, 102)) . rand(0, 1000); new $class(); } echo microtime(true)-$time;
上面的方法在我機器上執行大約的執行時間為0.31368708610535 左右..
這樣看來..整整慢了0.1 秒啊..
那為什麼會出現這種情況呢?
我的想法就是 include_path的設定PHP會去物理遍歷這個檔案..
這個可能在不同的檔案系統下所用的時間會有差別..但是大多數檔案系統都是基於B+樹去搜索檔案的..
而在PHP中如果直接用陣列來標明的話..array_key_exists最終是呼叫zend_hash_exists..也就是說是基於hash演算法的..
說到這裡 會不會是我生成的檔案目錄太歸於規則的緣故呢??