for vs foreach vs while which is faster for iterat

2020-02-12 03:42发布

问题:

which one is the fastest for iterating through arrays in php? or does another exist which is also faster for iterating through arrays?

回答1:

Even if there is any kind of difference, that difference will be so small it won't matter at all.

If you have, say, one query to the database, it'll take so long compared to the loop iterating over the results that the eternal debate of for vs foreach vs while will not change a thing -- at least if you have a reasonable amount of data.

So, use :

  • whatever you like
  • whatever fits your programming standard
  • whatever is best suited for your code/application

There will be plenty of other things you could/should optimize before thinking about that kind of micro-optimization.


And if you really want some numbers (even if it's just for fun), you can make some benchmark and see the results in practice.



回答2:

For me I pick my loop based on this:

foreach

Use when iterating through an array whose length is (or can be) unknown.

for

Use when iterating through an array whose length is set, or, when you need a counter.

while

Use when you're iterating through an array with the express purpose of finding, or triggering a certain flag.

Now it's true, you can use a FOR loop like a FOREACH loop, by using count($array)... so ultimately it comes down to your personal preference/style.



回答3:

In general there is no applicable speed differences between the three functions.

To provide benchmark results to demonstrate the efficiency of varying methods used to iterate over an array from 1 to 10,000.

Benchmark results of varying PHP versions: https://3v4l.org/a3Jn4

while $i++: 0.00077605247497559 sec
for $i++: 0.00073003768920898 sec
foreach: 0.0004420280456543 sec
while current, next: 0.024288892745972 sec
while reset, next: 0.012929201126099 sec
do while next: 0.011449098587036  sec //added after terminal benchmark
while array_shift: 0.36452603340149 sec
while array_pop: 0.013902902603149 sec

Takes into consideration individual calls for count with while and for

$values = range(1, 10000);
$l = count($values);
$i = 0;
while($i<$l){
   $i++;
}

$l = count($values);
for($i=0;$i<$l;$i++){
}

foreach($values as $val){
}

The below examples using while, demonstrate how it would be used less efficiently during iteration.

When functionally iterating over an array and maintaining the current position; while becomes much less efficient, as next() and current() is called during the iteration.

while($val = current($values)){
    next($values);
}

If the current positioning of the array is not important, you can call reset() or current() prior to iteration.

$value = reset($values);
while ($value) {
    $value = next($values);
}

do ... while is an alternative syntax that can be used, also in conjunction with calling reset() or current() prior to iteration and by moving the next() call to the end of the iteration.

$value = current($values);
do{
}while($value = next($values));

array_shift can also be called during the iteration, but that negatively impacts performance greatly, due to array_shift re-indexing the array each time it is called.

while($values){
   array_shift($values);
}

Alternatively array_reverse can be called prior to iteration, in conjunction with calling array_pop. This will avoid the impact from re-indexing when calling array_shift.

$values = array_reverse($values);
while($values) {
   array_pop($values);
}

In conclusion, the speed of while, for, and foreach should not be the question, but rather what is done within them to maintain positioning of the array.

Terminal Tests run on PHP 5.6.20 x64 NTS CLI:



回答4:

Correctly used, while is the fastest, as it can have only one check for every iteration, comparing one $i with another $max variable, and no additional calls before loop (except setting $max) or during loop (except $i++; which is inherently done in any loop statement).

When you start misusing it (like while(list..) ) you're better off with foreach of course, as every function call will not be as optimized as the one included in foreach (because that one is pre-optimized).

Even then, array_keys() gives you the same usability as foreach, still faster. And beyond that, if you're into 2d-arrays, a home-made 2d_array_keys will enable you to use while all the way in a much faster way then foreach can be used (just try and tell the next foreach within the first foreach, that the last foreach had <2d_array_keys($array)> as keys --- ).

Besides, all questions related to first or last item of a loop using a while($i

And

while ($people_care_about_optimization!==true){
 echo "there still exists a better way of doing it and there's no reason to use any other one";
}


回答5:

Make a benchmark test.

There is no major "performance" difference, because the differences are located inside the logic.

  • You use foreach for array iteration, without integers as keys.
  • You use for for array iteration with integers as keys.
  • etc.


回答6:

Remember that prefetching a lot of mysqli_result into a comfortable array can raise the question whether it is better to use for/foreach/while to cycle that array, but it's the wrong question about a bad solution that waste a lot of RAM.

So do not prefere this:

function funny_query_results($query) {
    $results = $GLOBALS['mysqli']->query($query);
    $rows = [];
    while( $row = $results->fetch_object() ) {
        $rows[] = $results;
    }
    return $rows;
}

$rows = funny_query_results("SELECT ...");
foreach($rows as $row) { // Uh... What should I use? foreach VS for VS while?
    echo $row->something;
}

The direct way getting one-by-one every mysql_result in a simple while is a lot more optimized:

$results = $mysqli->query("SELECT ...");
while( $row = $results->fetch_object() ) {
    echo $row->something;
}