はじめに
今回はfor文に関するtipsについて解説していきます。
for文の条件式にはcount($array)のような関数をいれない(変数に格納)
for文の条件式に関数を入れると遅くなるというtipsです。
例えば配列の要素数だけfor文を用いてループを回したいときに,
for ($j=0; $j<count($array); $j++) {}
このtipsでは下記のようにあらかじめ変数に格納してからの使用を勧めてます。
$count = count($array);
for ($j=0; $j<$count; $j++) {}
まずはサンプルプログラムを用意し,
benchmark_
<?php
$t = microtime(true);
$i = 0;
$a = null;
$array = array(1,2,3,4,5,6,7,8,9,10);
while ($i < 1000) {
$count = count($array);
for ($j=0;$j<$count;$j++) {
}
++$i;
}
$tmp = microtime(true) - $t;
var_dump($tmp);
?>
benchmark_
<?php
$t = microtime(true);
$i = 0;
$a = null;
$array = array(1,2,3,4,5,6,7,8,9,10);
while($i < 1000) {
for ($j=0;$j<count($array);$j++) {
}
++$i;
}
$tmp = microtime(true) - $t;
var_dump($tmp);
?>
ベンチマーク結果
$ php benchmark_for.php float(0.00143694877625) $ php benchmark_for_use_count.php float(0.00325417518616)
tips通りfor文の条件式に関数を用いないほうが速い結果となりました。それではどうしてこのような結果になるのか検証していきたいと思います。
vldを用いた解析
今回ははじめにvldを用いて解析を行います。vld
まずは,
$ tar xzf vld-0.9.1.tgz $ cd vld-0.9.1/ $ phpize $ ./configure $ make $ sudo make install
上記の手順でインストールすることができます。
それではvldを使ってみます。サンプルコードとして簡単なfor文のコードを用意します。
1 <?php
2 for ($i=0;$i<count(1);$i++) {
3 echo '';
4 }
5 ?>
実行方法はvld.
kajidai@laputa:~$ php -dvld.active=1 e.php Branch analysis from position: 0 Jump found. Position 1 = 10, Position 2 = 8 Branch analysis from position: 10 Return found Branch analysis from position: 8 Jump found. Position 1 = 5 Branch analysis from position: 5 Jump found. Position 1 = 1 Branch analysis from position: 1 filename: /home/kajidai/e.php function name: (null) number of ops: 12 compiled vars: !0 = $i line # op fetch ext return operands ------------------------------------------------------------------------------- 2 0 ASSIGN !0, 0 1 SEND_VAL 1 2 DO_FCALL 1 'count' 3 IS_SMALLER ~2 !0, $1 4 JMPZNZ 8 ~2, ->10 5 POST_INC ~3 !0 6 FREE ~3 7 JMP ->1 3 8 ECHO '' 4 9 JMP ->5 6 10 RETURN 1 11* ZEND_HANDLE_EXCEPTION
実行結果は上記のようになりました。それでは,
2:DO_
このようにforループが続く間,