アクセッサの速度を計測する in PHP
PHPで、「$obj->var」と「$obj->get_var()」にどのくらい速度差があるのかを調べてみた。
またjQueryのようにgetterとsetterを同じメソッドで行うようにしたいとき、引数があるかどうかを調べるのにfunc_num_args()を使った場合と使わない場合との速度差も測ってみた。
class Foo { var $var; /// ふつうのaccessor function var0() { return $this->var; /// getter } /// jQueryライクなaccessor: func_num_args() を使わない方法 function var1($arg=null) { if ($arg === null) { return $this->var; /// getter } else { $this->var = $arg; /// setter return $this; } } /// jQueryライクなaccessor: func_num_args() を使うバージョン function var2($arg=null) { if (func_num_args() === 0) { return $this->var; /// getter } else { $this->var = $arg; /// setter return $this; } } } $x = new Foo(); $x->var = 'foo'; $times = 1000000; /// 100万回 echo "-- ", $times, " times\n"; $N = $times / 10; echo '* $x->var: '; $t1 = microtime(true); for ($i = 0; $i < $N; $i++) { $x->var; $x->var; $x->var; $x->var; $x->var; $x->var; $x->var; $x->var; $x->var; $x->var; } $t2 = microtime(true); printf("%f sec\n", $t2 - $t1); echo '* $x->var0(): '; $t1 = microtime(true); for ($i = 0; $i < $N; $i++) { $x->var0(); $x->var0(); $x->var0(); $x->var0(); $x->var0(); $x->var0(); $x->var0(); $x->var0(); $x->var0(); $x->var0(); } $t2 = microtime(true); printf("%f sec\n", $t2 - $t1); echo '* $x->var1(): '; $t1 = microtime(true); for ($i = 0; $i < $N; $i++) { $x->var1(); $x->var1(); $x->var1(); $x->var1(); $x->var1(); $x->var1(); $x->var1(); $x->var1(); $x->var1(); $x->var1(); } $t2 = microtime(true); printf("%f sec\n", $t2 - $t1); echo '* $x->var2(): '; $t1 = microtime(true); for ($i = 0; $i < $N; $i++) { $x->var2(); $x->var2(); $x->var2(); $x->var2(); $x->var2(); $x->var2(); $x->var2(); $x->var2(); $x->var2(); $x->var2(); } $t2 = microtime(true); printf("%f sec\n", $t2 - $t1);
実行結果: (Mac OS X 10.6, Intel Core2 Duo 2GHz, PHP 5.2.11)
$ php hoge.php -- 1000000 times * $x->var: 0.106071 sec # 直アクセス * $x->var0(): 0.432793 sec # 通常のgetter * $x->var1(): 0.669569 sec # func_num_args() なし * $x->var2(): 0.853244 sec # func_num_args() あり
考察: