简体   繁体   English

do-while 是 php 中最快的循环吗?

[英]do-while is the fastest loop in php?

I have profiled for , while and do-while loops with something simple:我已经用一些简单的东西对forwhiledo-while循环进行了分析:

while ($var < 1000000) {
  ++$var;
}

do {
  ++$var;
} while ($var < 1000000);

for ($var = 0; $var < 1000000; ++$var) {
  //do nothing
}

by comparing microtime() before and after the loops.通过比较循环前后的 microtime()。

The do-while loop is by a considerable amount the fastest loop. do-while 循环在很大程度上是最快的循环。 do-while is actually faster than while by almost half. do-while实际上比while快了将近一半。 I know that they are for different purposes ( while checks the condition before the loop executes and do-while executes at least once ).我知道它们用于不同的目的( while在循环执行之前检查条件并且do-while至少执行一次)。

I know the general consensus is that while loops are frowned upon and do-while even more so.我知道普遍的共识是 while 循环不受欢迎,而 do-while 更是如此。

My question is why?我的问题是为什么? Considering how many for loops are used in PHP applications, shouldn't do-while be used more?考虑到 PHP 应用程序中使用了多少个 for 循环, do-while是不是应该多用一些? Even with an if statement to check a condition before the loop executes, the performance boost is considerable.即使使用if语句在循环执行之前检查条件,性能提升也是相当可观的。

My currently accepted answer is that code legibility is the suspect.我目前接受的答案是代码易读性是可疑的。

10 year Edit: 10 years ago, I was asked this question at a job interview. 10 年编辑: 10 年前,我在求职面试中被问到这个问题。 I went into the interview with the incorrect perception that while loops were frowned upon.我在接受采访时错误地认为 while 循环不受欢迎。 I learned this from my previous job where while loops were not allowed in code, as per instruction from my superior.我从之前的工作中学到了这一点,根据上级的指示,代码中不允许使用 while 循环。

The interview had gone well with management, then I was handed over to the lead programmer, he asked me what the fastest loop in PHP was, which I got incorrect and I did not get the job, this is why I asked the question on SO.管理层的面试进展顺利,然后我被交给了首席程序员,他问我 PHP 中最快的循环是什么,我说错了,我没有得到这份工作,这就是我在 SO 上问这个问题的原因.

10 years of experience has taught me a lot. 10年的经验教会了我很多。

  1. while loops are fine (its ludicrous to think I was taught otherwise) while 循环很好(认为我被教导否则很可笑)
  2. Micro-optimizations are truly evil (profile code, focus on bottle necks)微优化真的很邪恶(配置文件代码,专注于瓶颈)
  3. in 10 years, I have never re-written a loop for speed. 10 年来,我从未重新编写过速度循环。 I have however rewritten the logic inside the loop which was always the true bottleneck.然而,我重写了循环内部的逻辑,这始终是真正的瓶颈。
  4. There is a lot of strongly held but largely incorrect opinions in the programming field.在编程领域有很多强烈但基本上不正确的观点。 Stay the course, read up, experiment and question, be open to learning from better programmers and dont be afraid to be wrong.坚持到底,阅读,实验和提问,向更好的程序员学习,不要害怕犯错。
  1. Micro optimizations are evil .微优化是邪恶的 They reduce readability for no measurable performance gain.它们降低了可读性,没有可衡量的性能提升。 Even if your application does have loops with millions of iterators (which I doubt) the difference is still negligible.即使您的应用程序确实有包含数百万个迭代器的循环(我对此表示怀疑),差异仍然可以忽略不计。
  2. The difference between while / do while is smaller than you say: http://codepad.viper-7.com/M8cgt9 while / do while的区别比你说的要小: http : //codepad.viper-7.com/M8cgt9
  3. To understand why do while is marginally faster, look at the generated opcodes:要了解为什么do while稍微快一点,请查看生成的操作码:

     line # * op fetch ext return operands --------------------------------------------------------------------------------- # while loop 3 0 > ASSIGN !0, 0 4 1 > IS_SMALLER ~1 !0, 1000000 2 > JMPZ ~1, ->5 3 > PRE_INC !0 4 > JMP ->1 5 > > RETURN 1 # do while loop 3 0 > ASSIGN !0, 0 4 1 > PRE_INC !0 2 IS_SMALLER ~2 !0, 1000000 3 > JMPNZ ~2, ->1 4 > > RETURN 1 # for loop 3 0 > ASSIGN !0, 0 1 > IS_SMALLER ~1 !0, 1000000 2 > JMPZNZ 5 ~1, ->6 3 > PRE_INC !0 4 > JMP ->1 5 > > JMP ->3 6 > > RETURN 1

    The do while loop only has one jump statement ( JMPNZ ), whereas the while loop needs two ( JMPZ , JMP ). do while循环只有一个跳转语句( JMPNZ ),而while循环需要两个( JMPZJMP )。 The for loop needs three jump statements ( JMPZNZ , JMP , JMP ) and has generally more complex logic. for循环需要三个跳转语句( JMPZNZJMPJMP )并且通常具有更复杂的逻辑。

If you want a fast loop you must unroll it or use a duff device.如果您想要快速循环,您必须展开它或使用 duff 设备。

You can also shortcut the for-loop ( demo ):您还可以使用 for 循环 ( demo ) 的快捷方式:

for ($var = 0; ++$var < 10; ) {
   // do nothing
}

You can also shortcut the do-while loop ( demo ):您还可以缩短 do-while 循环(演示):

$var=0;
do {
    echo "Hello";
} while (++$var < 10);

But the opcodes are the same.但是操作码是一样的。

And here is a modified version of the duff device from php.net:这是来自 php.net 的 duff 设备的修改版本:

If you're already using the fastest algorithms you can find (on the order of O(1),      
O(n), or O(n log n)), and you're still worried about loop speed, unroll your loops  
using e.g., Duff's Device:

<?php
$n = $ITERATIONS % 8;
while ($n--) $val++;
$n = (int)($ITERATIONS / 8);
while ($n--) {
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
}
?>

(This is a modified form of Duff's original device, because PHP doesn't understand the (这是 Duff 原始设备的修改形式,因为 PHP 不理解
original's egregious syntax.)原始的令人震惊的语法。)

That's algorithmically equivalent to the common form:这在算法上等同于常见形式:

<?php
 for ($i = 0; $i < $ITERATIONS; $i++) {
   $val++;
}
?>

$val++ can be whatever operation you need to perform ITERATIONS number of times.

On my box, with no users, average run time across 100 samples with ITERATIONS =     
10000000 (10 million) is:
Duff version:       7.9857 s
Obvious version: 27.608 s

If you're interested in that kind of thing, you may find PHPBench interesting.如果您对这类事情感兴趣,您可能会发现PHPBench很有趣。

My personal opinion is that you should use while, do and for loops where they are most legible.我个人的意见是,您应该在最易读的地方使用 while、do 和 for 循环。 A 6% speed increase on an empty loop isn't significant enough if you're spending most of your time in the database.如果您的大部分时间都花在数据库中,那么在空循环上提高 6% 的速度并不够显着。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM