Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DoWhile是php中最快的循环吗?_Php_Performance_Do While - Fatal编程技术网

DoWhile是php中最快的循环吗?

DoWhile是php中最快的循环吗?,php,performance,do-while,Php,Performance,Do While,我用一些简单的东西分析了for、while和do-while循环: while ($var < 1000000) { ++$var; } do { ++$var; } while ($var < 1000000); for ($var = 0; $var < 1000000; ++$var) { //do nothing } while($var

我用一些简单的东西分析了for、while和do-while循环:

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

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

for ($var = 0; $var < 1000000; ++$var) {
  //do nothing
}
while($var<1000000){
++$var;
}
做{
++$var;
}而($var<1000000);
对于($var=0;$var<1000000;++$var){
//无所事事
}
通过比较循环前后的microtime()

do-while循环在很大程度上是最快的循环。“边做边做”实际上比“边做边做”快近一半。我知道它们的用途不同(while在循环执行之前检查条件,do while至少执行一次)

我知道普遍的共识是,虽然循环是不受欢迎的,但更是如此

我的问题是为什么?考虑到PHP应用程序中使用了多少for循环,不应该使用更多的for循环吗?即使使用if语句在循环执行之前检查条件,性能也会有相当大的提升

我目前接受的答案是代码的易读性是可疑的

10年编辑: 10年前,我在一次工作面试中被问到这个问题。我在参加面试时有一种错误的感觉,认为人们不喜欢打圈。我从以前的工作中学到了这一点,根据上级的指示,代码中不允许使用while循环

管理层的面试进行得很顺利,然后我被交给首席程序员,他问我PHP中最快的循环是什么,我的回答不正确,我没有得到这份工作,这就是为什么我这么问这个问题

10年的经验教会了我很多

  • 虽然循环是好的(认为我被教导了其他的想法是可笑的)
  • 微观优化确实是邪恶的(配置文件代码,关注瓶颈)
  • 10年来,我从未为速度重新编写过循环。然而,我重写了循环中的逻辑,这一直是真正的瓶颈
  • 在编程领域,有许多观点强烈,但基本上是错误的。坚持课程,阅读,实验和提问,向更好的程序员学习,不要害怕犯错

  • 如果你想要一个快速循环,你必须展开它或使用一个无用的设备

    您还可以创建for循环()的快捷方式:

    ($var=0;++$var<10;)的
    {
    //无所事事
    }
    
    您还可以设置do while循环()的快捷方式:

    $var=0;
    做{
    回音“你好”;
    }而(++$var<10);
    
    但是操作码是一样的

    下面是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++;
    }
    ?>
    
    如果你已经在使用你能找到的最快的算法(按O(1)的顺序),
    O(n)或O(n log n)),并且您仍然担心循环速度,请展开循环
    使用例如达夫装置:
    
    (这是Duff原始设备的一种修改形式,因为PHP不理解
    原文的语法太离谱了。)

    这在算法上等同于普通形式:

    <?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
    
    
    $val++可以是执行迭代次数所需的任何操作。
    在我的框中,在没有用户的情况下,100个迭代样本的平均运行时间=
    10000000(1000万)为:
    达夫版本:7.9857 s
    明显版本:27.608 s
    
  • 微优化是邪恶的。它们降低了可测量性能增益的可读性。即使您的应用程序确实有包含数百万个迭代器的循环(我对此表示怀疑),这种差异仍然可以忽略不计
  • while
    /
    do while
    之间的差异小于您所说的:
  • 要了解为什么
    do而
    稍微快一点,请查看生成的操作码:

    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
    
    do-while
    循环只有一个跳转语句(
    JMPNZ
    ),而
    while
    循环需要两个(
    JMPZ
    JMP
    )。
    for
    循环需要三个跳转语句(
    JMPZNZ
    JMP
    JMP
    ),并且通常具有更复杂的逻辑


  • 如果你对这类事情感兴趣,你可能会觉得有趣


    我个人的意见是,你应该使用while,do和for循环,在它们最清晰的地方。如果您将大部分时间花在数据库中,空循环上6%的速度提高是不够的。

    我不这么认为。如果他有报酬的话。如果他喜欢的话。当它有一百万个迭代器时,这是有意义的。@Jitamaro即使有几百万个迭代器,while/do while/for之间的差异与在循环中做事情所花费的时间相比几乎总是可以忽略不计的。循环可以忽略不计,算法速度更快,占用的内存更多important@Jitamaro字体不,他们是邪恶的。如果你不相信,就读这篇关于这个主题的文章吧…@icrmaxell:我浏览了你链接的那篇文章,但它是错的。这个90/10规则并不存在。这叫做帕累托规则,它说的是80/20%。你能发布你的基准测试结果吗?我从来没有看到过这样的共识,即虽然循环是坏的。它们是PHP工具箱中的一个工具,就像其他任何工具一样。谁会对while循环皱眉呢?只使用一半的时间听起来似乎很多,但你应该衡量你实际节省的时间。你只省了一半的钱。
    <?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
    
    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