For Loop Performance in PHP

FOR loop performance in PHP

The first way is slower because the count() function has to be called in every iteration of the loop. The count() method itself is pretty fast, but there is still some overhead in calling the function at all. By moving it outside the loop, you're performing what is called "loop invariant code motion", or sometimes "hoisting".

There's a whole family of optimizations like this that are interesting to learn about.

Having said all that, it seldom pays to stress about this very much. In your example here, the I/O of echoing the output is probably 10 times what you save through your "optimization". And if you do anything else at all inside your loop, your optimization means less and less.

I hate to be a wet blanket, but for more than 90% of your code, performance is a non-issue. Especially when you talk about web applications, which are more than 90% I/O to begin with.

Still, when you think your code is to blame, you should:

  1. Decide on the use case you need to optimize
  2. Measure your code performance
  3. Find the bottlenecks
  4. Identify the areas you can improve and decide whether it is worth your time to improve them.
  5. Make your code changes
  6. Go back to step 2

You'll nearly always discover that you need to improve your caching strategies and database optimization (which is just I/O optimization by another means), instead of twiddling code.

Performance of FOR vs FOREACH in PHP

My personal opinion is to use what makes sense in the context. Personally I almost never use for for array traversal. I use it for other types of iteration, but foreach is just too easy... The time difference is going to be minimal in most cases.

The big thing to watch for is:

for ($i = 0; $i < count($array); $i++) {

That's an expensive loop, since it calls count on every single iteration. So long as you're not doing that, I don't think it really matters...

As for the reference making a difference, PHP uses copy-on-write, so if you don't write to the array, there will be relatively little overhead while looping. However, if you start modifying the array within the array, that's where you'll start seeing differences between them (since one will need to copy the entire array, and the reference can just modify inline)...

As for the iterators, foreach is equivalent to:

$it->rewind();
while ($it->valid()) {
$key = $it->key(); // If using the $key => $value syntax
$value = $it->current();

// Contents of loop in here

$it->next();
}

As far as there being faster ways to iterate, it really depends on the problem. But I really need to ask, why? I understand wanting to make things more efficient, but I think you're wasting your time for a micro-optimization. Remember, Premature Optimization Is The Root Of All Evil...

Edit: Based upon the comment, I decided to do a quick benchmark run...

$a = array();
for ($i = 0; $i < 10000; $i++) {
$a[] = $i;
}

$start = microtime(true);
foreach ($a as $k => $v) {
$a[$k] = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {
$v = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => $v) {}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

And the results:

Completed in 0.0073502063751221 Seconds
Completed in 0.0019769668579102 Seconds
Completed in 0.0011849403381348 Seconds
Completed in 0.00111985206604 Seconds

So if you're modifying the array in the loop, it's several times faster to use references...

And the overhead for just the reference is actually less than copying the array (this is on 5.3.2)... So it appears (on 5.3.2 at least) as if references are significantly faster...

EDIT: Using PHP 8.0 I got the following:

Completed in 0.0005030632019043 Seconds
Completed in 0.00066304206848145 Seconds
Completed in 0.00016379356384277 Seconds
Completed in 0.00056815147399902 Seconds

Repeated this test numerous times and ranking results were consistent.

for loop vs while loop vs foreach loop PHP

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.

do-while is the fastest loop in php?

  1. Micro optimizations are evil. They reduce readability for no measurable performance gain. Even if your application does have loops with millions of iterators (which I doubt) the difference is still negligible.
  2. The difference between while / do while is smaller than you say: http://codepad.viper-7.com/M8cgt9
  3. To understand why do while is marginally faster, look at the generated opcodes:

    line     # *  op                           fetch          ext  return  operands
    ---------------------------------------------------------------------------------
    # while loop
    3 0 > ASSIGN !0, 0
    4 1 > IS_SMALLER ~1 !0, 1000000
    2 > JMPZ ~1, ->5
    3 > PRE_INC !0
    4 > JMP ->1
    5 > > RETURN 1
    # do while loop
    3 0 > ASSIGN !0, 0
    4 1 > PRE_INC !0
    2 IS_SMALLER ~2 !0, 1000000
    3 > JMPNZ ~2, ->1
    4 > > RETURN 1
    # for loop
    3 0 > ASSIGN !0, 0
    1 > IS_SMALLER ~1 !0, 1000000
    2 > JMPZNZ 5 ~1, ->6
    3 > PRE_INC !0
    4 > JMP ->1
    5 > > JMP ->3
    6 > > RETURN 1

    The do while loop only has one jump statement (JMPNZ), whereas the while loop needs two (JMPZ, JMP). The for loop needs three jump statements (JMPZNZ, JMP, JMP) and has generally more complex logic.

Improve PHP 'for' loop

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

In this example for every iteration it has to count($data) again.

for($i = 0, $iMax = count($data); $i <= $iMax; $i++){}

In this example it only needs to count($data) once.

That's the difference.

Efficient loops in PHP

In this specific case your first example is faster, simply because to evaluate the condition $i < count($array) PHP will execute count() after every loop. So following that logic it would be faster to use a variable in your condition, rather than a function.

The more practical approach would be to use foreach() as mentioned elsewhere.

PHP Loop Performance Optimization

Well, you haven't given a whole lot to go on. You don't describe your data, and you don't describe what your data is doing or when you need one object as opposed to another, and how those objects get released temporarily, and under what circumstances you need it back, and...

So anything anybody says here is going to be a complete shot in the dark.

...so along those lines, here's a shot in the dark.

If you are only comfortable holding x items in memory at any one time, set aside space for x items. Then, every time you access the object, make a note of the time (this might not mean clock time so much as it may mean the order in which you access them). Keep each item in a list (it may not be implemented in a list, but rather as a heap-like structure) so that the most recently used items appear sooner in the list. When you need to put a new one into memory, you replace the one that was used the longest time ago and then you move that item to the front of the list. You may need to keep another index of the items so that you know where exactly they are in the list when you need them. What you do then is look up where the item is located, link its parent and child pointers as appropriate, then move it to the front of the list. There are probably other ways to optimize lookup time, too.

This is called the LRU algroithm. It's a page replacement scheme for virtual memory. What it does is it delays your bottleneck (the disk I/O) until it's probably impossible to avoid. It is worth noting that this algorithm does not guarantee optimal replacement, but it performs pretty well nonetheless.

Beyond that, I would recommend parallelizing your code to a large degree (if possible) so that when one item needs to hit the hard disk to load or to dump, you can keep that processor busy doing real work.

< edit >
Based off of your comment, you are working on a neural network. In the case of your initial fedding of the data (before the correction stage), or when you are actively using it to classify, I don't see how the algorithm is a bad idea, unless there is just no possible way to fit the most commonly used nodes in memory.

In the correction stage (perhaps back-prop?), it should be apparent what nodes you MUST keep in memory... because you've already visited them!

If your network is large, you aren't going to get away with no disk I/O. The trick is to find a way to minimize it.
< /edit >

How to improve the speed of a for loop in PHP?

Don't call glob(). Just use a loop that processes each file that matches the pattern in numeric order. You can stop the loop when the file doesn't exist.

I assume there are no gaps in your numeric sequence of filenames.

if (($handle = fopen("../RC_PRODUCT_HUB.csv", "r")) !== FALSE) {
fgets($handle); // skip header line
while (($data = fgetcsv($handle, 9000000, ";")) !== FALSE){
if ($data[0] != null) {
for ($i = 1; file_exists($fileName = $path.$data[6].'_'.$data[7].'-'.$i.'.JPG'); ++$i) {
if (!in_array($fileName, $dataImage)){
$dataImage[$data[6] . '_' . $data[7]]['file'][$i] = $fileName;
$fileName = str_replace($path, '', $fileName);
if (!in_array($fileName, $dataImageTmp)){
$dataImageTmp[] = $fileName;
}
}
if (isset($dataImage[$data[6] . '_' . $data[7]]['TOTAL'])) {
$dataImage[$data[6] . '_' . $data[7]]['TOTAL']++;
} else {
$dataImage[$data[6] . '_' . $data[7]]['TOTAL'] = 1;
}
}
}
}
}

Are there performance issue of using while loop vs foreach/for loop?

You've listed this as "language-agnostic," but the answer will be language (or, rather, compiler)-specific.

Theoretically, foreach can be just as fast, if not faster, especially if the regular for loop keeps doing an expensive operation to test the Count.

Also, foreach works for a lazy-loaded collection, a regular for loop must know the number of item ahead of time.

Finally, even if foreach is slightly slower on your platform, it is highly unlikely the difference will matter, and it is much more maintainable than a for loop. Don't prematurely optimize. (This was, incidentally, the case for .NET for while, they've since tidied up the performance of enumerators.)

How to make array loop faster in PHP

<?php
$transport = array('foot', 'bike', 'car', 'plane');

foreach ($transport as $value) {
echo $value;
}
?>


Related Topics



Leave a reply



Submit