22

1st off I'm new to PHP. I have been using for loop,while loop,foreach loop in scripts. I wonder

  • which one is better for performance?
  • what's the criteria to select a loop?
  • which should be used when we loop inside another loop?

the code which I'm stuck with wondering which loop to be used.

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

It's pretty obvious that I can write the above code using while. Hope someone will help me out to figure out which loop should be better to be used.

AbsoluteƵERØ
  • 7,509
  • 1
  • 22
  • 34
Techie
  • 42,101
  • 38
  • 144
  • 232
  • 7
    It doesn't matter for performance. – Pekka Oct 11 '12 at 19:59
  • 4
    Stylistically, incremental `for` loops are very rarely used to iterate arrays in PHP. `foreach` is typically used instead since it can supply both the array key and value inside the loop. – Michael Berkowski Oct 11 '12 at 19:59

6 Answers6

34

which one is better for performance?

It doesn't matter.

what's the criteria to select a loop?

If you just need to walk through all the elements of an object or array, use foreach. Cases where you need for include

  • When you explicitly need to do things with the numeric index, for example:
  • when you need to use previous or next elements from within an iteration
  • when you need to change the counter during an iteration

foreach is much more convenient because it doesn't require you to set up the counting, and can work its way through any kind of member - be it object properties or associative array elements (which a for won't catch). It's usually best for readability.

which should be used when we loop inside another loop?

Both are fine; in your demo case, foreach is the simplest way to go.

Pekka
  • 418,526
  • 129
  • 929
  • 1,058
  • A `for` loop with a normal array is (strangely) a little bit faster than `foreach` iteration, but that is not a good reason to use it. It is much harder to read and doesn't allow us to substitute any Traversable in place of a normal array. – Francis Avila Oct 11 '12 at 20:05
  • 2
    @Francis yeah. Plus, the performance difference is in the *microseconds* even when run on 10k elements (see Jason's PHPBench link). The difference is really completely meaningless. – Pekka Oct 11 '12 at 20:09
  • 3
    well the foreach loop actually creates a copy of the variable in memory in order to iterate through it, vs you are directly iterating the original variable with the for loop. Negligible difference unless you are dealing with millions of elements. +1 for the awesome answer tho :P – Dave Lasley Oct 11 '12 at 22:42
  • @DaveLasley Is it true for generators also? – vaso123 Mar 28 '17 at 08:36
  • 1
    @vaso123 - A generator does not build a new array in memory, so my statement would be false in that scenario. – Dave Lasley Mar 29 '17 at 16:10
  • 1
    Thanks @DaveLasley for the intresting takes. You could use a while loop to shorten an array in memory with every loop ```while (!empty($tableList)) { $table = array_pop($tableList); }``` where the loop may have some validation logic – Tyler Miles Aug 12 '20 at 01:11
15

which one is better for performance?

Who cares? It won't be significant. Ever. If these sorts of tiny optimizations mattered, you wouldn't be using PHP.

what's the criteria to select a loop?

Pick the one that's easiest to read and least likely to cause mistakes in the future. When you're looping through integers, for loops are great. When you're looping through a collection like an array, foreach is great, when you just need to loop until you're "done", while is great.

This may depend on stylistic rules too (for example, in Python you almost always want to use a foreach loop because that's "the way it's done in Python"). I'm not sure what the standard is in PHP though.

which should be used when we loop inside another loop?

Whichever loop type makes the most sense (see the answer above).

In your code, the for loop seems pretty natural to me, since you have a defined start and stop index.

Brendan Long
  • 49,408
  • 17
  • 130
  • 172
7

Check http://www.phpbench.com/ for a good reference on some PHP benchmarks.

The for loop is usually pretty fast. Don't include your count($rows) or count($all) in the for itself, do it outside like so:

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

Placing the count($all) in the for loop makes it calculate this statement for each loop. Calculating the value first, and then using the calculation in the loop makes it only run once.

Jason
  • 1,102
  • 7
  • 8
  • 2
    Disagree with you on both counts here. The benchmarks don't really matter - what real world difference do 200 microseconds make in a PHP script? There will be none. And look at the code you show and compare it to `foreach ($all)`. Which is easier to read and maintain? – Pekka Oct 11 '12 at 20:06
  • I concur, plus foreach is much nicer to read as well. for loops can sometimes get jumbled with all the references to the key. – DevNinjaJeremy Jul 20 '16 at 14:15
6
  • For performance it does not matter if you choose a for or a while loop, the number of iterations determine execution time.
  • If you know the number of iterations at forehand, choose a for loop. If you want to run and stop on a condition, use a while loop
JvdBerg
  • 21,117
  • 8
  • 31
  • 54
2
  • for loop is more appropriate when you know in advance how many iterations to perform
  • While loop is used in the opposite case(when you don't know how many iterations are needed)
  • For-Each loop is best when you have to iterate over collections.

To the best of my knowledge, there is little to no performance difference between while loop and for loop i don't know about the for-each loop

yohannes
  • 3,828
  • 3
  • 28
  • 53
2

Performance: Easy enough to test. If you're doing something like machine learning or big data you should really look at something that's compiled or assembled and not interpreted though; if the cycles really matter. Here are some benchmarks between the various programming languages. It looks like do-while loop is the winner on my systems using PHP with these examples.

$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);

Criteria: while, for, and foreach are the major control structures most people use in PHP. do-while is faster than while in my tests, but largely underused in most PHP coding examples on the web.

for is count controlled, so it iterates a specific number of times; though it is slower in my own results than using a while for the same thing.

while is good when something might start out as false, so it can prevent something from ever running and wasting resources.

do-while at least once, and then until the condition returns false. It's a little faster than a while loop in my results, but it's going to run at least once.

foreach is good for iterating through an array or object. Even though you can loop through a string with a for statement using array syntax you can't use foreach to do it though in PHP.

Control Structure Nesting: It really depends on what you're doing to determine while control structure to use when nesting. In some cases like Object Oriented Programming you'll actually want to call functions that contain your control structures (individually) rather than using massive programs in procedural style that contain many nested controls. This can make it easier to read, debug, and instantiate.

AbsoluteƵERØ
  • 7,509
  • 1
  • 22
  • 34