PHPBench.com在每个页面加载上运行快速基准脚本。在foreach测试中,当我加载它时,foreach的运行时间比第三个例子长4到10倍。
为什么本地语言结构显然比自己执行逻辑要慢?
答案 0 :(得分:9)
也许它与foreach在数组副本上工作的事实有关?
或者它可能与以下事实有关:在使用foreach循环时,在每次迭代时,内部数组指针都会更改,指向下一个元素?
引用foreach
's manual page的相关部分:
注意:除非引用了数组, foreach在一份副本上运作 指定的数组而不是数组 本身。 foreach有一些副作用 在数组指针上。
据我所知,你链接到的第三个测试没有做这两件事 - 这意味着两个测试都没有做同样的事情 - 这意味着你没有比较两种编写相同代码的方式
(我也会说这种微优化在实际应用中根本不重要 - 但我猜你已经知道了,只是出于好奇而被问到了)
在这个测试中还有一件事感觉不对:它只进行一次测试;对于“更好”的测试,不止一次测试所有这些测试可能是有用的 - 时间大约为100微秒,不需要太多就可以产生巨大的差异。
(考虑到第一次测试在几次刷新后变化在300%和500%之间......)
对于那些不想点击的人来说,这是第一次测试(我已经获得了3xx%,443%和529%):
foreach($aHash as $key=>$val) {
$aHash[$key] .= "a";
}
第三个(100%):
$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++) {
$aHash[$key[$i]] .= "a";
}
答案 1 :(得分:2)
对不起,网站弄错了。这是我自己的脚本,显示两者的速度几乎相同,事实上,foreach更快!
<?php
function start(){
global $aHash;
// Initial Configuration
$i = 0;
$tmp = '';
while($i < 10000) {
$tmp .= 'a';
++$i;
}
$aHash = array_fill(100000000000000000000000, 100, $tmp);
unset($i, $tmp);
reset($aHash);
}
/* The Test */
$t = microtime(true);
for($x = 0;$x<500;$x++){
start();
$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++) $aHash[$key[$i]] .= "a";
}
print (microtime(true) - $t);
print ('<br/>');
$t = microtime(true);
for($x = 0;$x<500;$x++){
start();
foreach($aHash as $key=>$val) $aHash[$key] .= "a";
}
print (microtime(true) - $t);
?>
如果查看测试的源代码:http://www.phpbench.com/source/test2/1/和http://www.phpbench.com/source/test2/3/,您可以看到$ aHash在每次迭代后都没有重新填充到初始数据。它在开头创建一次,然后每次测试运行X次。从这个意义上说,你在每次迭代中使用不断增长的$ aHash ......在psuedocode中:
iteration 1: $aHash[10000000000000]=='aaaaaa....10000 times...a';
iteration 2: $aHash[10000000000000]=='aaaaaa....10001 times...a';
iteration 2: $aHash[10000000000000]=='aaaaaa....10002 times...a';
随着时间的推移,所有测试的数据对于每次迭代都会变得越来越大,因此当然通过迭代100,array_keys方法更快,因为它总是具有相同的键,其中foreach循环必须与不断增长的数据集竞争并将值存储在数组中!
如果你在服务器上运行我上面提供的代码,你会清楚地看到foreach更快,更整洁,更清晰。
如果网站的作者打算让他的测试做它做的事情,那么当然不清楚,否则,这是一个无效的测试。
答案 2 :(得分:0)
这种微观测量的基准测试结果应该被忽视,这些测量来自一个受到极端负载和其他影响的实时,繁忙的网络服务器。这不是一个基准测试的环境。