所以我决定实际量化一些事情,以获得一些真实的数字。这是基线代码,一个循环构建一个包含 100000 个整数的大数组。
$x = array();
for ($idx=0; $idx<100000; $idx++)
$x[] = $idx;
平均执行时间:85 毫秒。这包括启动 PHP、解析程序、运行程序和退出的时间。现在,我添加另一个循环遍历数组:
for ($idx=0; $idx<count($x); $idx++) {
;
}
平均执行时间:105 毫秒。当您减去 85 毫秒的设置时间时,您可以看到迭代 100,000 个成员数组只需要 20 毫秒。
现在我们添加循环不变代码运动:
$m = count($x);
for($idx=0; $idx<$m; $idx++) {
;
}
平均执行时间:90 毫秒。
一方面,这种节省是巨大的。那是 5 毫秒的循环迭代时间,而不是 20 毫秒。所以你可以说这是节省了 75%!
另一方面,它是 15 毫秒。比大多数人在一个荒谬的大阵列上注意到的时间要少。
但这是一个什么都不做的数组。让我们看看当我们输出一些数据时会发生什么:
$m = count($x);
for ($idx=0; $idx<$m; $idx++) {
echo $idx;
}
现在执行时间是 200 毫秒。哦,看,我只打印了循环索引。我什至没有输出数组的内容。
这很愚蠢。让我们再次更改程序以回显数组的内容,而不仅仅是查看计数器:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx];
新的执行时间是 212 毫秒。因此,访问和回显数组内容比回显循环计数器要长 5%。
让我们接受某人先前的建议并展开循环。过去我在 C/C++ 中使用过这个效果很好:
$m = count($x);
for ($idx=0; $idx<$m; $idx+=5) {
echo $x[$idx];
echo $x[$idx+1];
echo $x[$idx+2];
echo $x[$idx+3];
echo $x[$idx+4];
}
现在我们在说话!我们降至 206 毫秒。哦,等等,对于一些不好玩的代码来说,这大约是 3% 的改进。输出看起来很糟糕。它只是一串没有空格或任何东西的数字。
让我们摆脱循环展开,让输出更好一点:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo "{$x[$idx]}\n";
执行时间为 400 毫秒。嗯。这需要很多额外的时间(相对而言)只是为了获得一些格式。也许使用字符串替换会让我们付出一些代价。让我们尝试字符串连接:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx] . "\n";
新时间为 390 毫秒。好一点。让我们尝试用空格而不是换行符分隔数字:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx] . " ";
哇哦,我们又回到了 224 毫秒。对了!但是发生了什么?好吧,我在我的 Unix 终端上运行所有这些,并且在单独的行上输出数字比在换行的一行上输出它们要慢得多。
换句话说,终端程序的滚动速度比我们所做的任何事情都具有更大的影响。