php-continue状态的性能

php-continue状态的性能,php,loops,continue,micro-optimization,Php,Loops,Continue,Micro Optimization,我今天在工作中想:使用continuestate是否有更快的方法来获得结果 for ($i=0; $i<5000; $i++) { if (!($i % 2)) { continue; } do_something_odd($i); } 对于($i=0;$i无论如何,不确定您是否仍在寻找答案: 一般而言,以下各项之间没有性能差异: for (...) { if (condition) continue; some work; }

我今天在工作中想:使用
continue
state是否有更快的方法来获得结果

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

对于($i=0;$i无论如何,不确定您是否仍在寻找答案:

一般而言,以下各项之间没有性能差异:

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

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

当然,要优化的第一件事是高级算法、数据结构等。如果您使用了高级算法,并且需要最大限度地提高性能,那么主要的敌人就是条件/分支和错误预测。有许多不同的技术用于此:

  • 如果可能,将条件移到循环外部
  • 将循环拆分为多个循环
  • 通常,与逐位运算符相比,乘法、除法和模运算速度非常慢
  • 某些条件可以替换为无分支语句
  • 取消循环以最小化测试数量
  • 衡量每一项变化

    例如,稍微修改代码版本以计算范围[-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";
    
    定义('N',100000000);
    $start=microtime(真);
    $odd_count=0;
    $偶数=0;
    
    对于($i=-N;$iIt会有一点不同,所以我更愿意关注优化那些真正重要的东西。尽管如此,如果你只想要奇数,你可以做
    $i+2
    ,而不是
    $i++
    @Qirel我知道像
    $i+2
    这样的数学循环,但我把它作为一个例子。我想当你在实际工作时包含大量数据的循环,循环中有许多循环,mutch的速度会有多快?实际上,我发布的是错误的,语法是
    $I+=2
    ,而不是
    $I+2
    。但是如果你想测试哪一个更快,只需运行一个基准测试。我认为可读性在PHP中更重要。我是
    if($I%2==0)的粉丝继续;
    而不是像
    if(!($i%2))
    那样的否定,并且更喜欢提前退出而不是if/else。也就是说,运行一个基准测试并告诉我们您的发现。有趣的是,在PHP7中,我发现您的第二次测试比其他测试快。最后一次测试(7.0)对我来说,在PHP5.6中运行9.57s和8.2s的第二个版本就像你描述的那样。很有趣!@IvijanStefanStipić可能是php7引入了一些优化,使得
    if%
    &
    快,或者是bug使得
    &
    if%
    慢。我会尝试使用
    (int)
    casting。无论如何,这就是你必须测量一切的原因
    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";
    
    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++;
    
    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;
    }
    
    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;
    }