关于php:循环之间的区别

关于php:循环之间的区别

The difference between loops

它是关于PHP的,但毫无疑问,许多相同的注释将适用于其他语言。

简而言之,PHP不同类型的循环有何不同? 一个比另一个更快/更好吗?还是我应该简单地放在最易读的循环中?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for ($i = 0; $i < 10; $i++)
{
    # code...
}


foreach ($array as $index => $value)
{
    # code...
}


do
{
    # code...
}
while ($flag == false);

For循环和While循环是进入条件循环。他们首先评估条件,因此即使条件不满足,与循环关联的语句块也不会运行

此for循环块中的语句将运行10次,$ i的值将为0到9;

1
2
3
4
for ($i = 0; $i < 10; $i++)
{
        # code...
}

while循环完成相同的操作:

1
2
3
4
5
6
$i = 0;
while ($i < 10)
{
    # code...
   $i++
}

Do-while循环是退出条件循环。确保执行一次,然后在重复执行该块之前先评估条件

1
2
3
4
5
do
{
        # code...
}
while ($flag == false);

foreach用于从头到尾访问数组元素。在foreach循环开始时,将数组的内部指针设置为数组的第一个元素,在下一步中,将其设置为数组的第二个元素,依此类推,直到数组结束。在循环块中,当前数组项的值可用作$ value,而当前项的键可用作$ index。

1
2
3
4
foreach ($array as $index => $value)
{
        # code...
}

您可以使用while循环执行相同的操作,像这样

1
2
3
4
5
6
7
8
9
while (current($array))
{
    $index = key($array);  // to get key of the current element
    $value = $array[$index]; // to get value of current element

    # code ...  

    next($array);   // advance the internal array pointer of $array
}

最后:PHP手册是您的朋友:)


@brendan:

您引用的文章已严重过时,并且信息完全是错误的。特别是最后一点(使用for代替Foreach)具有误导性,并且本文中提供的理由不再适用于.NET的现代版本。

虽然IEnumerator确实使用虚拟调用,但实际上可以由现代编译器内联。此外,.NET现在知道泛型和强类型枚举器。

有许多性能测试可以最终证明for通常不快于Foreach。这是一个例子。


PHP基准


这是CS101,但由于没有其他人提到过,虽然while循环在代码块之前评估其条件,而do-while在代码块之后评估,所以do-while循环始终保证至少运行一次其代码块,无论情况如何。


当访问数组的元素时,为清楚起见,我会尽可能使用一个foreach,并且仅在需要实际索引值(例如,多个数组中的相同索引)时才使用for。由于for循环使这一切变得太容易了,因此这也使打字错误的机会降到最低。总的来说,PHP可能不是一个过于担心性能的地方。最后但并非最不重要的一点是,for和foreach具有(或应该具有;我不是PHP-er)相同的Big-O时间(O(n)),因此您可能正在查看少量的内存使用情况或时间上持续或线性的轻微波动。


With a foreach loop, a copy of the original array is made in memory to use inside.

Foreach is nice, but has one important caveat: you can't modify the enumerable you're iterating.

如果您通过引用而不是值来传递,那么这两个都不是问题:

1
 foreach ($array as &$value) {

我认为自PHP 5起就允许这样做。


每个循环构造都有不同的用途。

for-用于循环特定次数的迭代。

foreach-用于遍历集合中的所有值。

while-用于循环播放,直到满足条件为止。

在这三种情况中,"在"情况下最有可能在大多数情况下提供最佳性能。当然,如果您执行以下操作,则基本上是在重写" for"循环(在c#中性能更高)。

1
2
3
4
5
6
7
$count = 0;
do
{
   ...
   $count++;
}
while ($count < 10);

它们都有不同的基本用途,但也可以以相同的方式使用。这完全取决于您要解决的特定问题。


在性能方面,foreach比

http://forums.asp.net/p/1041090/1457897.aspx


通过foreach循环,将在内存中创建原始数组的副本以在内部使用。您不应该在大型结构上使用它们;一个简单的for循环是一个更好的选择。您可以在大型的非数字索引结构上更有效地使用while循环,如下所示:

1
while(list($key, $value) = each($array)) {

但是,这种方法对于简单的小型结构尤其难看。

while循环更适合循环流,或者如以下在PHP中经常看到的示例所示:

1
while ($row = mysql_fetch_array($result)) {

几乎所有时间,不同的循环都是可互换的,这将归结为a)效率或b)清晰度。

如果您知道不同类型循环的效率之间的权衡,那么可以回答您的原始问题:使用看起来最干净的循环。


在这两种情况下,性能均不会显着提高。尽管对于进行比迭代更复杂的任务很有用,但forwhile在功能上是等效的。

Foreach很不错,但有一个重要警告:您不能修改要迭代的可枚举。因此,请勿删除,添加或替换其中的条目。当然,修改条目(例如更改其属性)是可以的。


在遍历常规(索引索引)数组时使用第一个循环,在处理关联数组时使用foreach循环。在我看来,这似乎很自然,可以帮助代码流动并提高可读性。至于do ... while循环,当我不得不做的事情不仅仅是遍历数组时,我会使用它们。

不过,我不确定会有任何性能上的好处。


推荐阅读