【问题标题】:for loop vs while loop vs foreach loop PHPfor 循环 vs while 循环 vs foreach 循环 PHP
【发布时间】:2012-10-02 14:04:28
【问题描述】:

我是 PHP 新手。我一直在脚本中使用 for 循环、while 循环、foreach 循环。我想知道

  • 哪一种性能更好?
  • 选择循环的标准是什么?
  • 当我们在另一个循环中循环时应该使用哪个?

我一直想知道要使用哪个循环的代码。

for($i=0;$i<count($all);$i++)
{
 //do some tasks here
 for($j=0;$j<count($rows);$j++)
 {
  //do some other tasks here 
 }
}

很明显,我可以使用 while 编写上述代码。希望有人能帮我弄清楚应该使用哪个循环更好。

【问题讨论】:

  • 性能无关紧要。
  • 在风格上,增量 for 循环很少用于 PHP 中的数组迭代。通常使用 foreach 代替,因为它可以在循环内提​​供数组键和值。

标签: php performance loops nested-loops control-structure


【解决方案1】:

哪个性能更好?

没关系。

选择循环的标准是什么?

如果您只需要遍历对象或数组的所有元素,请使用foreach。您需要for的情况包括

  • 当您明确需要对数字索引进行操作时,例如:
  • 当您需要在迭代中使用上一个或下一个元素时
  • 当您需要在迭代期间更改计数器时

foreach 更方便,因为它不需要您设置计数,并且可以通过任何类型的成员工作 - 无论是对象属性还是关联数组元素(for 不会'抓不到)。它通常最利于可读性。

当我们在另一个循环中循环时应该使用哪个?

两者都很好;在您的演示案例中,foreach 是最简单的方法。

【讨论】:

  • 带有普通数组的for 循环(奇怪地)比foreach 迭代快一点,但这不是使用它的好理由。它更难阅读,并且不允许我们用任何 Traversable 代替普通数组。
  • @Francis 是的。此外,即使在 10k 个元素上运行,性能差异也只有 微秒(请参阅 Jason 的 PHPBench 链接)。差别真的完全没有意义。
  • 好吧,foreach 循环实际上在内存中创建了一个变量的副本,以便对其进行迭代,而不是直接使用 for 循环迭代原始变量。除非您处理数百万个元素,否则差异可以忽略不计。 +1 很棒的答案:P
  • @vaso123 - 生成器不会在内存中构建新数组,因此在这种情况下我的陈述将是错误的。
  • 感谢@DaveLasley 的精彩拍摄。您可以使用 while 循环在每个循环 while (!empty($tableList)) { $table = array_pop($tableList); } 中缩短内存中的数组,其中循环可能有一些验证逻辑
【解决方案2】:

哪个性能更好?

谁在乎?这不会很重要。曾经。如果这些微小的优化很重要,你就不会使用 PHP。

选择循环的标准是什么?

选择最容易阅读且以后最不可能出错的内容。当您遍历整数时,for 循环很棒。当您循环遍历数组之类的集合时,foreach 很棒,当您只需要循环直到“完成”时,while 很棒。

这也可能取决于风格规则(例如,在 Python 中,您几乎总是希望使用 foreach 循环,因为这是“在 Python 中完成的方式”)。我不确定 PHP 的标准是什么。

当我们在另一个循环中循环时应该使用哪个?

哪种循环类型最有意义(请参阅上面的答案)。

在您的代码中,for 循环对我来说似乎很自然,因为您已经定义了开始和停止索引。

【讨论】:

    【解决方案3】:

    查看http://www.phpbench.com/ 以获得一些 PHP 基准测试的良好参考。

    for 循环通常非常快。不要将您的 count($rows) 或 count($all) 包含在 for 本身中,像这样在外面做:

    $count_all = count($all);
    for($i=0;$i<$count_all;$i++)
    {
        // Code here
    }
    

    将 count($all) 放在 for 循环中,使其为每个循环计算此语句。先计算值,然后在循环中使用计算使其只运行一次。

    【讨论】:

    • 在这两个方面都不同意你的观点。基准并不重要——PHP 脚本中 200 微秒在现实世界中有何不同?不会有。并查看您显示的代码并将其与foreach ($all) 进行比较。哪个更易于阅读和维护?
    • 我同意,而且 foreach 也更易于阅读。 for 循环有时会与对键的所有引用混淆。
    【解决方案4】:
    • 对于性能而言,选择forwhile 循环并不重要,迭代次数决定了执行时间。
    • 如果您知道正手的迭代次数,请选择for 循环。如果您想在某个条件下运行和停止,请使用 while 循环

    【讨论】:

      【解决方案5】:
      • 当你事先知道有多少个时,for 循环更合适 要执行的迭代
      • 而循环在相反的情况下使用(当你不知道有多少 需要迭代)
      • 当您必须迭代集合时,For-Each 循环是最佳选择。

      据我所知,while 循环和 for 循环之间几乎没有性能差异,我不知道 for-each 循环

      【讨论】:

        【解决方案6】:

        性能: 很容易测试。如果您正在做机器学习或大数据之类的事情,那么您应该真正查看的是编译组装而不是解释的东西;如果周期真的很重要。 Here are some benchmarks between the various programming languages. 看起来 do-while 循环是我系统上使用 PHP 的赢家。

        $my_var = "some random phrase";
        
        function fortify($my_var){
            for($x=0;isset($my_var[$x]);$x++){
                echo $my_var[$x]." ";
            }
        }
        
        function whilst($my_var){
            $x=0;
            while(isset($my_var[$x])){
               echo $my_var[$x]." ";
               $x++;
            }
        }
        
        function dowhilst($my_var){
            $x=0;
            do {
               echo $my_var[$x]." ";
               $x++;
            } while(isset($my_var[$x]));
        }
        
        function forstream(){
            for($x=0;$x<1000001;$x++){
                //simple reassignment
                $v=$x;
            }
            return "For Count to $v completed";
        }
        
        function whilestream(){
            $x=0;
            while($x<1000001){
                $v=$x;
                $x++;
            }
            return "While Count to 1000000 completed";
        }
        
        function dowhilestream(){
            $x=0;
            do {
                $v=$x;
                $x++;
            } while ($x<1000001);
            return "Do while Count to 1000000 completed";
        }
        
        function dowhilestream2(){
            $x=0;
            do {
                $v=$x;
                $x++;
            } while ($x!=1000001);
            return "Do while Count to 1000000 completed";
        }
        
        $array = array(
            //for the first 3, we're adding a space after every character.
                'fortify'=>$my_var,
                'whilst'=>$my_var,
                'dowhilst'=>$my_var,
           //for these we're simply counting to 1,000,000 from 0
           //assigning the value of x to v 
                'forstream'=>'',
                'whilestream'=>'',
                'dowhilestream'=>'',
           //notice how on this one the != operator is slower than
           //the < operator
                'dowhilestream2'=>''
                );
        
        function results($array){
            foreach($array as $function=>$params){
        
        
              if(empty($params)){
                $time= microtime();
                $results = call_user_func($function);  
              } elseif(!is_array($params)){
                $time= microtime();  
                $results = call_user_func($function,$params);
              } else {
                $time= microtime();  
                $results = call_user_func_array($function,$params);
              }
              $total = number_format(microtime() - $time,10);
              echo "<fieldset><legend>Result of <em>$function</em></legend>".PHP_EOL;
              if(!empty($results)){
                  echo "<pre><code>".PHP_EOL;
                  var_dump($results);
                  echo PHP_EOL."</code></pre>".PHP_EOL;
              }
              echo "<p>Execution Time: $total</p></fieldset>".PHP_EOL;
            }
        }
        
        results($array);
        

        标准: whileforforeach 是大多数人在 PHP 中使用的主要控制结构。在我的测试中,do-whilewhile 快,但在网络上的大多数 PHP 编码示例中基本上没有得到充分利用。

        for 是计数控制的,所以它会迭代特定的次数;虽然我自己的结果比使用while 来做同样的事情要慢。

        while 非常适合以 false 开头的东西,因此它可以防止某些东西运行并浪费资源。

        do-while 至少一次,然后直到条件返回false。在我的结果中,它比 while 循环快一点,但它至少会运行一次。

        foreach 非常适合遍历arrayobject。即使您可以使用数组语法通过 for 语句循环字符串,但在 PHP 中却不能使用 foreach 来执行此操作。

        控制结构嵌套:这真的取决于你在做什么来确定嵌套时使用的控制结构。在某些情况下,例如面向对象编程,您实际上希望(单独)调用包含您的控制结构的函数,而不是使用包含许多嵌套控件的过程风格的大量程序。这可以使其更易于阅读、调试和实例化。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-09
          • 1970-01-01
          • 2014-10-19
          • 2023-04-02
          • 2015-07-03
          • 2012-01-05
          相关资源
          最近更新 更多