PHP: Most Common Mistakes (part 2) – Using Post Increment Instead of Pre Increment

Posted: April 17th, 2011 | Author: | Filed under: Common PHP Mistakes, PHP, Programming/Development | 5 Comments »

The Problem

I want to first point out that the mistake I am about to discuss holds true for many languages. However, I’m going to focus on its presence in PHP because that’s my favorite language and I would be willing to bet that very few experienced PHP developers, let alone beginners, are aware that they are making this error. It should also be noted that everything I talk about in this post can also apply to decrementing too.

Incrementing is the process of adding to a numerical variable’s value. Incrementing primarily takes place in loops. In basic practice, incrementing can be achieved in three different ways in PHP. Here is each method demonstrated using a while loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Method 1, using standard variable modification, no shorthand incrementer used:
$i = 0;
while ($i < 20000)
{
     // do stuff here
     $i = $i + 1;
}
 
// Method 2, using post incrementation, by far the most popular method:
$i = 0;
while ($i < 20000)
{
     // do stuff here
     $i++;
}
 
// Method 3, using pre incrementation:
$i = 0;
while ($i < 20000)
{
     // do stuff here
     ++$i;
}
It first must be pointed out that all three methods here achieve the exact same thing. However, the problem arises when you compare their speeds. Method 1, although I don’t think it’s widely used, is by far the slowest out of the three. The next slowest method is method 2, which also happens to be by far the most popular method for incrementing or decrementing a variable. I find this troubling and I see it as a major issue. Method 3 performs the best, hands down, 100% of the time. If you are curious as to why, I’ll give a brief explanation a little later in this post.

Why is this a Bad Mistake?

I love efficient code. All developers should love efficient code. I have debated semantics like incrementing methods with experienced developers and I constantly hear an argument that goes like this: “all of the methods achieve the same thing and in the end, there is only a tiny difference between their speeds. The developer should use whichever method they feel most comfortable with.” This is a sentiment I strongly reject. The way I see it, when there are three methods of doing something, and one of them outperforms the other two 100% of the time, it no longer comes down to developer choice about which one they should use. They should be using the more efficient method. Now, I think it is important to note that in many cases code can be made more efficient by reducing readability or reducing re-usability and flexibility. I am not suggesting anyone does that. In the case of incrementing, all three methods share similar syntax and most importantly, they are all one line of code.

The Solution

Like I have already stated, the solution to this problem is very simple. When merely incrementing or decrementing variable, always, with no exceptions, use pre incrementation (++$i). Whether it just be on its own line or in a for loop counter, pre incrementation will always be the fastest. However, it needs to be noted that in other situations that aren’t straight incrmentation, post and pre do serve different purposes. The difference is in the value they return. Pre incrementation returns the value of the variable after it has been incremented, and post incrementation returns the value before the variable is incremented. In straight incrementation/decrementation where the returned value is not being used, this being most cases, pre incrementation should always be used because of its performance advantage. But for any case where the return value is being used, post and pre incrementation need to both be considered to see which will accomplish the task in the best manner.

I don’t want to get too much into the inner-workings of PHP, but the reason for the performance advantage of pre incrementation is derived from its functionality when compared to post. Pre incrementation is able to just increment the variable and then return the value. This requires little overhead and no copying of values. On the other hand, for post incrementation, the value of the variable being modified must first be copied to a temporary location so it can be returned. This of course requires some overhead and hence decreases performance.

Conclusion

Pre incrementation and decrementation should always be used when the returned value is irrelevant. Earlier in this post, I described three possible methods of incrementing a variable. I wanted to speed test them for proof, so I set up a simple test for each method using a while loop set to iterate five-hundred million times. You are probably asking, “Why five-hundred million iterations?” I decided to make each loop about the size of the Facebook user-base. This makes each loop very realistic for real-world use. There are many situations where a program will need to iterate through an entire user-base, so it makes sense.

Here is my simple speed test program: (note that this is not the most effective way to test speed, because it doesn’t use averages, but it gets the job done for this test, and it’s simple to understand)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
set_time_limit(500);
 
$test = '';
$i = 0;
$time_start = microtime(true);
while ($i < 500000000)
{
    $test = 'a val';
    $i++;
}
 
$time_end = microtime(true);
$run_time = $time_end - $time_start;
echo 'Run time with i++: ' . $run_time . '<br/>';
 
 
$test = '';
$i = 0;
$time_start = microtime(true);
while ($i < 500000000)
{
    $test = 'a val';
    ++$i;
}
 
$time_end = microtime(true);
$run_time = $time_end - $time_start;
echo 'Run time with ++i: ' . $run_time . '<br/>';
 
$test = '';
$i = 0;
$time_start = microtime(true);
while ($i < 500000000)
{
    $test = 'a val';
    $i = $i + 1;
}
 
$time_end = microtime(true);
$run_time = $time_end - $time_start;
echo 'Run time with i = i + 1: ' . $run_time . '<br/>';
 
?>
And the results when I ran it:
Run time with i++: 118.29421687126
Run time with ++i: 112.87914013863
Run time with i = i + 1: 131.7296547889
Just as expected. Pre incrementation sees a fairly significant speed improvement over post incrementation, and normal assignment isn’t even close.

I realize that five-hundred million iterations is a very large loop, but I also contend that efficiency in cases like this is even vital for small examples. Instead of huge loops, think about concurrent users. If a PHP page is requested by 200 visitors at the same time, the server(s) needs to take care of each request. Why give it more overhead, no matter how minuscule that overhead might be? Even tiny performance issues are heavily magnified by mass amounts of requests. That is why I truly believe that a developer should write code as efficiently as possible and anticipate for mass amounts of concurrent requests. You can’t really go wrong with that philosophy.

5 Comments on “PHP: Most Common Mistakes (part 2) – Using Post Increment Instead of Pre Increment”

  1. 1 JebPotly said at 1:07 pm on May 10th, 2011:

    AWESOME! I’ve contended this several times and never seen it written so coherently. Thank you

  2. 2 Piskvor said at 4:54 am on August 5th, 2013:

    You are neglecting one significant issue: developer time is not free, therefore the amount of optimizations has a hard limit. IMNSHO, it is a right-out waste of time to bother with such femto-optimizations (this isn’t even micro-optimizations) and ignore the real elephants in the room. I will eat my hat if there’s any production code where pre-increment is a major performance bottleneck: even your contrived example in a do-nothing tight loop has failed to show a _significant_ difference.

    When writing new code – by all means, use the best methods available, even pre-increment; but to claim that this is a “vital” issue for efficiency is disingenuous at the very best.

    TL;DR: “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil” -Donald Knuth

  3. 3 DFox said at 12:55 am on October 20th, 2013:

    Piskvor, the only thing I agree with you on is that developer time is not free. Though I’m not sure how that’s relevant when talking about an optimization that costs no developer time. I always hate when people bring up “premature optimization.” It’s such a ridiculously overused term. It’s impossible to say, without substantial amounts of data, that slight optimizations won’t improve the performance and effectiveness of a large, high-throughput application. It’s been proven time and time again that even milliseconds in page load time of a web application can greatly impact the quantities of user-interactions. For any project that you consider worthwhile, why would you not use optimizations that cost absolutely no developer time, don’t sacrifice any readability, and is always more efficient? I’m not saying I believe it will automatically make a noticeable difference in the scheme of the application, but the possibility is always there.

    Just because most developers have been trained to use a less-efficient method of doing something, it doesn’t mean that should have to be the norm.

  4. 4 Delbert said at 8:20 pm on May 18th, 2014:

    Today, I went to the beach with my children. I found a sea shell and
    gave it to my 4 year old daughter and said “You can hear the ocean if you put this to your ear.” She placed the shell to her ear
    and screamed. There was a hermit crab inside and it pinched her ear.
    She never wants to go back! LoL I know this is totally off topic but I had
    to tell someone!

    My blog – skillfulcrease131.page.tl [Delbert]

  5. 5 Johnk759 said at 4:26 am on June 29th, 2014:

    Hi there! Someone in my Myspace group shared this site with us so I came to give it a appear. Im definitely loving the details. Im bookmarking and will likely be tweeting this to my followers! Outstanding blog and great style and style. dcceadfddeec


Leave a Reply