2016-12-03 62 views
1

我今天在工作的时候在想:用continue状态有没有更快的方法来获得结果?php - 继续状态的性能

for ($i=0; $i<5000; $i++) { 
    if (!($i % 2)) { 
     continue; 
    } 
    do_something_odd($i); 
} 

更快普通循环与的if/else或使用继续是更快跳跃的结果?

我在问,因为性能和优化。

+3

这将是一个非常差别不大,所以我宁愿集中精力优化的东西,实际上很重要。尽管如此,如果你只是想要奇数,你可以做'$ i + 2'而不是'$ i ++'。 – Qirel

+0

@Qirel我知道数学的循环,比如'$ I + 2',但我把这个像例子。我在想,当你用真正的循环来处理一堆数据,循环中有很多循环,mutch会更快,什么是什么? –

+0

其实,我贴错了,语法是'$ I + = 2',不'$ I + 2'。尽管如果你想测试哪一个更快,只需运行一个基准。 – Qirel

回答

1

不知道,如果你还在寻找答案,反正:

一般

,之间不存在性能差异:

for (...) { 
    if (condition) continue; 
    some work; 
} 

for (...) { 
    if (!condition) some work; 
} 

我建议避免continue,只是因为我认为它的可读性较差,所以基本上是goto

当然首先要优化的是高层算法,数据结构等等。如果你完成了它,你需要最大化性能 - 主要敌人是条件/分支和错误预测。有许多不同的技术为:

外循环
  1. 运动状态,如果有可能
  2. 拆分环成多的人
  3. 通常乘法,除法和模量是相当缓慢的,相较于逐位运算符
  4. 有些条件可以用网点的语句来代替
  5. 取消ROOL循环,以减少测试次数

测量每一个变化

例如稍微修改您的代码,以计算在范围偶数和奇数的数目的版本[-N,N],不包括0:

define('N', 100000000); 

$start = microtime(true); 

$odd_count = 0; 
$even_count = 0; 
for ($i=-N; $i<=N; $i++) 
    if ($i != 0) 
     if ($i % 2 != 0) $odd_count++; 
     else $even_count++; 

$end = microtime(true); 

echo 'odd: '.$odd_count."\n"; 
echo 'even: '.$even_count."\n"; 
echo 'time: '.($end-$start)."\n"; 

我们当然可以代替用简单的公式,这整个循环(这是高层次算法优化),还是让我们尝试用循环的工作:

平均时间我多次运行主机上:9.1秒

应用1 ST和第二法则:

for ($i=-N; $i<0; $i++) 
     if ($i % 2 != 0) $odd_count++; 
     else $even_count++; 
for ($i=1; $i<=N; $i++) 
     if ($i % 2 != 0) $odd_count++; 
     else $even_count++; 

时间:7.7秒

应用第三和第四规则:

for ($i=-N; $i<0; $i++) { 
    $t = $i & 1; 
    $odd_count += $t; 
    $even_count += 1 - $t; 
} 
for ($i=1; $i<=N; $i++) { 
    $t = $i & 1; 
    $odd_count += $t; 
    $even_count += 1 - $t; 
} 

时间:7.3秒

而且最终的结果:

for ($i=-N; $i<0;) { 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
} 
for ($i=1; $i<=N;) { 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
} 

时间:7。0秒

+0

有趣的是,在PHP 7我发现你的第二个测试是比别人快。最后一个测试(7.0)为我运行9.57s和第二个8.2s。在PHP5.6就像你描述。有趣! –

+1

@IvijanStefanStipić其可能PHP7引入了一些优化这让'如果'%快于'&',也可能是错误的同时取得'&'然后慢'如果'%:)我会尝试使用'(INT)'铸件。无论如何,这就是为什么你必须衡量一切 –