php - 继续状态的表现

php - performance of continue state

我今天在工作时在想:有没有使用 continue 状态更快地获得结果的方法?

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

是使用 if/else 的普通循环更快还是使用 continue 跳过结果更快?

我问是因为性能和优化。

无论如何,不​​确定您是否仍在寻找答案:

总的来说,两者之间没有性能差异:

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

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

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

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

  1. 如果可能,将条件移出循环
  2. 将循环拆分为多个循环
  3. 与按位运算符相比,乘法、除法和模运算通常非常慢
  4. 部分条件可以用无分支语句代替
  5. 取消循环以减少测试次数

衡量每一个变化

例如,稍微修改您的代码版本以计算 [-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 秒

应用第一条和第二条规则:

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 秒

应用第 3 条和第 4 条规则:

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 秒