请考虑以下代码:
$start = microtime();
for($i = 2; $i < 100; $i++)
{
for($y = 2; $y <= sqrt($i); $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
continue 2;
}
}
echo $i.',';
}
echo "\nFinished in " . (microtime() - $start);
鉴于上面的代码有效地使用continue 2来打破内部循环并跳过内部循环后的任何代码,为什么下面的代码在看起来做得更多时平均执行得更快:
$start = microtime();
for($i = 2; $i < 100; $i++)
{
$flag = true;
for($y = 2; $y <= sqrt($i); $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
$flag = false;
break;
}
}
if($flag === true) echo $i.',';
}
echo "\nFinished in " . (microtime() - $start);
感谢您的任何意见。
__ _ __ 更新 的 __ _ __ _ __ _ __ _ < / p>
感谢您的反馈,但我们似乎错过了这一点。无论这是否是一个好的编程实践,我都试图理解为什么性能差异(微小但一致)不在我预期的偏见之内。
真实到微量时间的传递似乎微不足道,因为两个样本都是使用相同的方法测量的,具有相同的开销和相同的不准确性。
使用“平均”一词暗示了多次测试。
仅举例说明请使用microtime(true)考虑以下小样本,其显示与使用microtime()相同的模式。
我知道这是一个小样本,但模式非常明确:
继续 0.00037288665771484 0.00048208236694336 0.00046110153198242 0.00039386749267578 0.0003662109375
歇 0.00033903121948242 0.00035715103149414 0.00033307075500488 0.00034403800964355 0.00032901763916016
感谢您的关注,并感谢您提供进一步的反馈。
__ _ ___ 更新进一步调查 的 __ _ __ _ __ _ ___
有趣的是,如果从代码中删除了echo语句,则continue的执行速度会更快,并且echo语句就位更快。
请考虑以下代码示例,并考虑结果是否冲突取决于是否删除了echo语句:
<?php
$breakStats = array();
$continueStats = array();
ob_start();
for($i = 0; $i < 10000; $i++)
{
$breakStats[] = doBreakTest();
$continueStats[] = doContinueTest();
}
ob_clean();
echo "<br/>Continue Mean " . (array_sum($continueStats) / count($continueStats));
echo "<br/>Break Mean " . (array_sum($breakStats) / count($breakStats));
function doBreakTest()
{
$start = microtime(true);
for($i = 2; $i < 100; $i++)
{
$flag = true;
$root = sqrt($i);
for($y = 2; $y <= $root; $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
$flag = false;
break;
}
}
}
if($flag === true) echo $i . '';
return microtime(true) - $start;
}
function doContinueTest()
{
$start = microtime(true);
for($i = 2; $i < 100; $i++)
{
$root = sqrt($i);
for($y = 2; $y <= $root; $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
echo $i . '';
continue 2;
}
}
}
return microtime(true) - $start;
}
回声陈述:
继续平均值0.00014134283065796 中断均值0.00012669243812561
不存在回声声明:
继续平均值0.00011746988296509 中断均值0.00013022310733795
请注意,通过从break和flag测试中删除echo语句,我们还删除了($ flag === true)检查,因此加载应该减少,但在这种情况下继续获胜。 w ^
因此,在纯粹的继续n与break + flag场景中,似乎continue n是更快的contstruct。但是添加相同数量的相同echo语句和continue n性能标志。
从逻辑上讲,这对我来说是有意义的,继续n应该更快,但我希望看到与存在的echo语句相同。
这显然是生成的操作码的区别,并且echo语句的位置(内部循环与外部循环)是否有人知道看到生成的操作码的方法?我想这是我最需要的,因为我正在努力了解内部发生的事情。
谢谢:)
答案 0 :(得分:2)
是的,第一个有点快。这是因为它只是跳出继续2并打印$ i。
第二个例子有更多工作要做...为$ flag变量赋值,跳出循环,检查$ flag的值,检查$ flag的类型(也比较)然后输出$ i。它有点慢(简单的逻辑)。
无论如何,有任何目的吗?
我的一些比较结果
0.0011570 < 0.0012173
0.0011540 < 0.0011754
0.0011820 < 0.0012036
0.0011570 < 0.0011693
0.0011970 < 0.0012790
已使用:PHP 5.3.5
@ Windows
(1000次尝试; 100%优先更快)
0.0011570 < 0.0012173
0.0005000 > 0.0003333
0.0005110 > 0.0004159
0.0003900 < 0.0014029
0.0003950 > 0.0003119
0.0003120 > 0.0002370
已使用:PHP 5.3.3
@ Linux
(1000次尝试; 32%优先:68%秒更快)
0.0006700 > 0.0004863
0.0003470 > 0.0002591
0.0005360 > 0.0004027
0.0004720 > 0.0004229
0.0005300 > 0.0004366
已使用:PHP 5.2.13
@ Linux
(1000次尝试; 9%优先:91%秒更快)
抱歉,我没有更多服务器可供测试:)现在我认为它主要取决于硬件(也可能取决于操作系统)。
通常:只证明Linux服务器比在Windows上运行的服务器更快:)
答案 1 :(得分:2)
continue 2
版本对我来说稍微快一些。但这些并不是您通常需要关注的事物类型。考虑:
for($y = 2; $y <= sqrt($i); $y++)
您在此处计算每次迭代的sqrt
。只需将其更改为:
$sqrt = sqrt($i);
for($y = 2; $y <= $sqrt; $y++)
将比在两个几乎相同的循环样式之间切换提供更好的改进。
如果您发现您更容易理解,则应使用continue 2
。电脑并不在乎。
要解决有关查看操作码的更新,请参阅:
php -d vld.active=1 -d vld.execute=0 -f foo.php