5

Possible Duplicate:
Is there a performance difference between i++ and ++i in C++?

In terms of usage of the following, please rate in terms of execution time in C. In some interviews i was asked which shall i use among these variations and why.

a++
++a
a=a+1
a+=1
Community
  • 1
  • 1
abhi4eternity
  • 448
  • 3
  • 8
  • 19
  • 4
    You really think you were supposed to answer based on efficiency? Also, your title and question do not agree. I'm taking a guess and editing this. – Matt Ball Aug 24 '10 at 14:28
  • 4
    Is this C, or C++? Because in C++, you can't assume a++ and a+=1 are the same operation (or that the other will even exist if the first one does). – Caleb Huitt - cjhuitt Aug 24 '10 at 14:30
  • @Caleb: ...or that the code even compiles. – fredoverflow Aug 24 '10 at 14:32
  • @Caleb Huitt - cjhuitt: Oooh good one. I just assumed it was an integer operation. I'm glad *you're* not interviewing me ;) – FrustratedWithFormsDesigner Aug 24 '10 at 14:33
  • Don't blame yourself. The interview question itself is problematic, and the fact that the same question is "popular" among interviewers is even more troublesome. You can find the genuine answer in the book "Effective C++: 50 Specific Ways to Improve Your Programs and Design". I doubt if the interviewers can comprehend this book at all. – rwong Aug 24 '10 at 14:39
  • 1
    I find the army of answers charging here, all within 2 (!) minutes, interesting. Are we all victims of the same triggering sort of questions? – wilhelmtell Aug 24 '10 at 14:40
  • Part of the reason I think the 3rd and 4th choices are stupid is that not all iterators are written to support random access, nor that `+=` was always defined ... but it's still good to read http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html and try implement as much as possible (given time) – rwong Aug 24 '10 at 14:47
  • possible duplicate of http://stackoverflow.com/questions/24886/is-there-a-performance-difference-between-i-and-i-in-c - sorry used wrong link in vote – Potatoswatter Aug 24 '10 at 14:54
  • 2
    -1 for idiocy. If you don't use the result, they are all **identical** on any non-broken compiler. – R.. GitHub STOP HELPING ICE Aug 24 '10 at 23:50
  • 2
    For future reference, the use of the imperative mode in the title *really* grates on my nerves. **Don't** tell me what to do, ask a question. – dmckee --- ex-moderator kitten Aug 25 '10 at 00:16

10 Answers10

92

Here is what g++ -S produces:

void irrelevant_low_level_worries()
{
    int a = 0;
//  movl    $0, -4(%ebp)

    a++;
//  incl    -4(%ebp)

    ++a;
//  incl    -4(%ebp)

    a = a + 1;
//  incl    -4(%ebp)

    a += 1;
//  incl    -4(%ebp)
}

So even without any optimizer switches, all four statements compile to the exact same machine code.

NullUserException
  • 83,810
  • 28
  • 209
  • 234
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 2
    @NullUserException: Err, no, he turned optimization off. +1 – Billy ONeal Aug 24 '10 at 14:36
  • Make `a` a global variable and then it won't be optimized away. – wilhelmtell Aug 24 '10 at 14:37
  • 1
    @Null: a is being incremented, so that is not optimized away. if (a++) or (++a) is used, then it's a different situation and can't be compared. This question is mostly for "for (int i = 0; i < 10; ++i) { ... }" – stefaanv Aug 24 '10 at 14:38
  • 4
    @Null: Are you talking about using `a++` vs. `++a` as part of a larger expression? But then it is irrelevant to measure the performance, because the two expressions yield different results... – fredoverflow Aug 24 '10 at 14:41
  • Fred, we could make them comparable by using `<` in one comparison and `<=` in the other. – Steven Sudit Aug 24 '10 at 14:43
6

You can't rate the execution time in C, because it's not the C code that is executed. You have to profile the executable code compiled with a specific compiler running on a specific computer to get a rating.

Also, rating a single operation doesn't give you something that you can really use. Todays processors execute several instructions in parallel, so the efficiency of an operation relies very much on how well it can be paired with the instructions in the surrounding code.

So, if you really need to use the one that has the best performance, you have to profile the code. Otherwise (which is about 98% of the time) you should use the one that is most readable and best conveys what the code is doing.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 6
    Translation: This is a stupid question, to which there is no meaningful answer. – Steven Sudit Aug 24 '10 at 14:44
  • 2
    @Steven Sudit: Not a stupid question, but pointless and outdated. The question is based on conditions that were relevant 10 years ago, but today's hardware and programming culture puts completely different focus on how you write code. – Guffa Aug 24 '10 at 15:08
  • I see your point, but I'm not sure I agree. Even in the days of poorly-optimizing C compilers and processor speeds in the low MHz range, this question didn't have much value. – Steven Sudit Aug 24 '10 at 16:08
  • @Steven Sudit: Yes, you are right that the question was never of great value, but once upon a time it was at least possible to determine exactly how long each instruction would take on a given computer. – Guffa Aug 24 '10 at 16:14
  • That's true. Now, as you pointed out, we can only discuss the average time when in a given context, and then only on a given computer. I used to be able to rattle off how many (best-case) clock cycles an operation would take, but that's become somewhat pointless. – Steven Sudit Aug 24 '10 at 16:26
3

The circumstances where these kinds of things actually matter is very rare and few in between. Most of the time, it doesn't matter at all. In fact I'm willing to bet that this is the case for you.

What is true for one language/compiler/architecture may not be true for others. And really, the fact is irrelevant in the bigger picture anyway. Knowing these things do not make you a better programmer.

You should study algorithms, data structures, asymptotic analysis, clean and readable coding style, programming paradigms, etc. Those skills are a lot more important in producing performant and manageable code than knowing these kinds of low-level details.

Do not optimize prematurely, but also, do not micro-optimize. Look for the big picture optimizations.

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
1

This depends on the type of a as well as on the context of execution. If a is of a primitive type and if all four statements have the same identical effect then these should all be equivalent and identical in terms of efficiency. That is, the compiler should be smart enough to translate them into the same optimized machine code. Granted, that is not a requirement, but if it's not the case with your compiler then that is a good sign to start looking for a better compiler.

wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
1

For most compilers it should compile to the same ASM code.

Gustavo Puma
  • 993
  • 12
  • 27
0

Same.

For more details see http://www.linux-kongress.org/2009/slides/compiler_survey_felix_von_leitner.pdf

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

Well, you could argue that a++ is short and to the point. It can only increment a by one, but the notation is very well understood. a=a+1 is a little more verbose (not a big deal, unless you have variablesWithGratuitouslyLongNames), but some might argue it's more "flexible" because you can replace the 1 or either of the a's to change the expression. a+=1 is maybe not as flexible as the other two but is a little more clear, in the sense that you can change the increment amount. ++a is different from a++ and some would argue against it because it's not always clear to people who don't use it often.

In terms of efficiency, I think most modern compilers will produce the same code for all of these but I could be mistaken. Really, you'd have to run your code with all variations and measure which performs best.

(assuming that a is an integer)

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
0

I can't see why there should be any difference in execution time, but let's prove me wrong.

a++

and

++a

are not the same however, but this is not related to efficiency.

When it comes to performance of individual lines, context is always important, and guessing is not a good idea. Test and measure is better

shodanex
  • 14,975
  • 11
  • 57
  • 91
  • 1
    Yes, it is related to efficiency. With `++a`, we just increment a and return the new value. With `a++`, either we have to store `a` into a register, then increment `a`, and then return the value in the register, or we have to increment `a` and return the new value minus `1`. This is obviously optimized away if you aren't using the return value. – alternative Aug 24 '10 at 14:50
0

In an interview, I would go with two answers:

  1. At first glance, the generated code should be very similar, especially if a is an integer.
  2. If execution time was definitely a known problem - you have to measure it using some kind of profiler.
Jeff
  • 1,969
  • 3
  • 21
  • 35
  • Id modify 2) to 2') : If execution time was definetly a known problem, most likely the problem is somewhere else. So do 2) – Tom Aug 24 '10 at 14:57
0

It depends on the context, and if we are in C or C++. In C the code you posted (except for a-- :-) will cause a modern C compiler to produce exactly the same code. But by a very high chance the expected answer is that a++ is the fastest one and a=a+1 the slowest, since ancient compilers relied on the user to perform such optimizations.

In C++ it depends of the type of a. When a is a numeric type, it acts the same way as in C, which means a++, a+=1 and a=a+1 generate the same code. When a is a object, it depends if any operator (++, + and =) is overloaded, since then the overloaded operator of the a object is called.

Also when you work in a field with very special compilers (like microcontrollers or embedded systems) these compilers can behave very differently on each of these input variations.

Rudi
  • 19,366
  • 3
  • 55
  • 77
  • 1
    Why would `a++` be faster than `++a`? :) – fredoverflow Aug 24 '10 at 14:43
  • 1
    @FredOverflow, Thats correct. The answer is wrong. `++a` will always be at least as fast as `a++`, faster if you need the return value. – alternative Aug 24 '10 at 14:48
  • @FredOverflow It depends on the opinion of the interviewer. – Rudi Aug 24 '10 at 14:53
  • 3
    @FredOverflow, when `a` is a pointer, the full expression is `total += *(a++)` or similar, and you are on a processor that has a post-incrementing indirect addressing mode but no pre-incrementing one. e.g. M68000. Yes, in the olden days, we used to use `*(p++)` and `*(--p)`, but only very infrequently `*(++p)` or `*(p--)`, as those matched the addressing modes available in hardware. (And in fact, those two happen to match what you usually want to do with a pointer to a NUL-terminated string or other sentinel-terminated list, which is why they're the ones implemented in hardware.) – John Marshall Aug 24 '10 at 15:53
  • -1 for misleading statement that there's a high chance of performance being different. – R.. GitHub STOP HELPING ICE Aug 24 '10 at 23:52