for循环 vs while循环 vs foreach循环 PHP

22

首先,我是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循环来编写上述代码。希望有人能帮我找出哪种循环更好用。


7
不影响性能。 - Pekka
4
在PHP中,以增量方式进行'for'循环来迭代数组的做法在风格上很少使用。通常使用foreach,因为它可以在循环内部提供数组键和值。 - Michael Berkowski
6个回答

34

哪个循环更适合性能?

没有区别。

选择循环的标准是什么?

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

  • 当您需要明确地处理数字索引时,例如:
  • 当您需要在迭代中使用前一个或下一个元素时
  • 当您需要在迭代过程中更改计数器时

foreach 更加便捷,因为它不需要设置计数,并且可以遍历任何类型的成员 - 不管是对象属性还是关联数组元素(for无法捕获)。通常最易读。

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

两种方式都可以;在您的演示案例中,foreach 是最简单的方法。


使用正常数组的 for 循环比 foreach 迭代略快一些,但这并不是使用它的好理由。这更难以阅读,并且不允许我们替换任何可遍历对象来代替普通数组。 - Francis Avila
2
@Francis 是的。而且,即使在运行10k个元素时(请参见Jason的PHPBench链接),性能差异也只有微秒级别。这种差异实际上是完全没有意义的。 - Pekka
3
foreach循环实际上会在内存中创建一个变量的副本来进行迭代,而for循环直接迭代原始变量。除非处理数百万个元素,否则差异可以忽略不计。虽然如此,这是一篇很棒的答案! - Dave Lasley
@DaveLasley 这对生成器也适用吗? - vaso123
1
@vaso123 - 生成器不会在内存中构建一个新的数组,因此在这种情况下我的陈述是错误的。 - Dave Lasley
1
感谢@DaveLasley提供有趣的见解。您可以使用while循环来缩短每个循环中内存中的数组while (!empty($tableList)) { $table = array_pop($tableList); },其中该循环可能具有一些验证逻辑。 - Richard Tyler Miles

16

哪种更适合提高性能?

谁在乎呢?它不会有明显的影响。如果这些微小的优化很重要,你就不会使用PHP。

选择循环的标准是什么?

选择最容易阅读且最不容易在将来出错的循环方式。当您遍历整数时,使用for循环非常好。当您遍历像数组这样的集合时,foreach循环非常好;当您只需要循环直到“完成”时,while循环非常好。

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

在内部循环时应该使用哪个?

无论哪种循环类型最合理(参见上面的答案)。

在您的代码中,for循环对我来说似乎非常自然,因为您有一个定义好的开始和结束索引。


7

请查看http://www.phpbench.com/,了解一些PHP基准测试的好参考资料。

for循环通常非常快。不要在for循环中包含count($rows)或count($all),请在外部执行,例如:

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

在for循环中放置count($all)会使它在每次循环时计算该语句。先计算值,然后在循环中使用计算结果只会运行一次。

2
在这两个问题上,我不同意您的看法。基准测试并不重要 - 在PHP脚本中200毫秒会有什么真正的区别?没有任何区别。再看看您展示的代码,将其与“foreach($all)”进行比较。哪个更容易阅读和维护? - Pekka
我同意,而且foreach更容易阅读。for循环有时会因为所有对键的引用而变得混乱。 - DevNinjaJeremy

6
  • 无论您选择使用for循环还是while循环,在性能上没有区别,迭代次数决定了执行时间。
  • 如果您事先知道迭代次数,请选择for循环。如果您想在满足条件时运行并停止,请使用while循环

2
性能: 测试很容易。如果您正在进行类似机器学习或大数据的工作,应该使用编译或汇编语言而不是解释语言,这样如果时钟周期真的很重要。在这里有各种编程语言之间的一些基准测试。看起来在我的系统上,使用这些示例的PHP中,do-while循环是获胜者。
$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 进行迭代。

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

2
  • 当您事先知道要执行多少次迭代时,for循环更为适用。
  • 当您不知道需要执行多少次迭代时,使用While循环。
  • 当您必须遍历集合时,For-Each循环最好。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接