7

I was wondering, if we have if-else condition, then what is computationally more efficient to check: using the equal to operator or the not equal to operator? Is there any difference at all?

E.g., which one of the following is computationally efficient, both cases below will do same thing, but which one is better (if there's any difference)?

Case1:

if (a == x)
{
    // execute Set1 of statements
}
else
{
    // execute Set2 of statements
}

Case 2:

if (a != x)
{
    // execute Set2 of statements
}
else
{
    // execute Set1 of statements
}

Here assumptions are most of the time (say 90% of the cases) a will be equal to x. a and x both are of unsigned integer type.

jsist
  • 5,223
  • 3
  • 28
  • 43
  • I'm unsure operation wise, however I tend to put the `most likely` case in the if statement and the less likely in the else(ifs), especially if we're talking inside a loop. I imagine it in best case could help the CPU with branch prediction, but most likely the compiler has optimized it somehow anyway :) – Jite Dec 12 '12 at 12:16
  • I suggest you read up on branch prediction and taking your assumption into account, the branch predictor would optimize things so that neither would be any slower. – Tony The Lion Dec 12 '12 at 12:16
  • if 90% of the times a==x, then your current structure looks better to me – Chubsdad Dec 12 '12 at 12:36
  • 3
    @TonyTheLion: Branch prediction varies greatly in different processor models. When the branch prediction is static (thus, not the result of cached information from actual execution), the order in which things are written in source code can matter. It can also matter when one direction is more frequent than the other but the selection changes frequently (thus clouding the prediction from cache). These are rare situations that most programmers will not encounter, but they exist, matter greatly to certain programmers, and should not be denied. – Eric Postpischil Dec 12 '12 at 13:02
  • @EricPostpischil ...and are definitely not resolved at the level of Java source code. – Marko Topolnik Dec 12 '12 at 13:05
  • There's no way to answer the question without knowing the underlying hardware. And it is certainly not specific to C, C++, or Java. – Puppy Dec 12 '12 at 13:08
  • @MarkoTopolnik: The question was originally tagged with Java, C++, and C, and there are compilers for C and C++ at least that do provide some control over branch prediction. – Eric Postpischil Dec 12 '12 at 13:19
  • @EricPostpischil The main point is that this cannot possibly be answered by a blanket statement covering any and all languages. I definitely see the point of taking these concerns seriously when writing performance-critical C implementation of a number-crunching algorithm---and no point at all when writing **any** kind of Java code. – Marko Topolnik Dec 12 '12 at 13:27
  • http://stackoverflow.com/search?q=if+statement+efficiency –  Dec 12 '12 at 13:27
  • @MarkoTopolnik: Yes, people asking questions often ask questions that cannot be answered by blanket statements. Nonetheless, they are seeking information, there is information to be offered, and information about specific situations or other approaches may be relevant and useful. The goal is to help people. – Eric Postpischil Dec 12 '12 at 13:42
  • @EricPostpischil As far as I can see, both of us did exactly that. I am sure you agree. – Marko Topolnik Dec 12 '12 at 13:43
  • As the Q has been tagged as C/C++, you may be interested in knowing what @EricPostpischil has pointed out in the comments Some compilers like `gcc` provide certain mechanisms to generate code wherein the branch prediction will be favored based on your code See [this](http://stackoverflow.com/questions/109710/likely-unlikely-macros-in-the-linux-kernel) post regarding such code optimization in kernel code. Please be sure when to make use of them (as pointed out in various answers it may not be typically needed) Note that such code can be problem to port. Make sure you know what you're doing! – another.anon.coward Dec 12 '12 at 13:45

14 Answers14

10

Generally it shouldn't matter for performance which operator you use. However it is recommended for branching that the most likely outcome of the if-statement comes first.

Crog
  • 1,112
  • 8
  • 16
  • 2
    As AlexWien mentions it is often preferable to write it the way that is more logical to the reader. You won't gain much if anything but if you normally hit the first case the cache may be more efficiently used when a few CPU/GPU cycles are vital. – Crog Dec 12 '12 at 12:21
10

Usually what you should consider is; what is the simplest and clearest way to write this code? IMHO, the first, positive is the simplest (not requiring a !)

In terms of performance there is no differences as the code is likely to compile to the same thing. (Certainly in the JIT for Java it should)

For Java, the JIT can optimise the code so the most common branch is preferred by the branch prediction.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    `non-negative is the simplest` +1 - in a few of the companies I've worked for it was *required* to use a non-negative (in a situation like this) because it's more intuitive for humans to read and thus less error prone. – Mike Dec 12 '12 at 12:47
  • 2
    @Mike: If they are going to make a rule like that, it should require that the condition be positive, not that it be non-negative. Or else somebody should be making rules for the rule-makers. – Eric Postpischil Dec 12 '12 at 12:55
8

In this simple case, it makes no difference. (assuming a and x are basic types) If they're class-types with overloaded operator == or operator != they might be different, but I wouldn't worry about it.

For subsequent loops:

if ( c1 )   { }
else if ( c2 ) { }
else ...

the most likely condition should be put first, to prevent useless evaluations of the others. (again, not applicable here since you only have one else).

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
5

GCC provides a way to inform the compiler about the likely outcome of an expression:

if (__builtin_expect(expression, 1))
…

This built-in evaluates to the value of expression, but it informs the compiler that the likely result is 1 (true for Booleans). To use this, you should write expression as clearly as possible (for humans), then set the second parameter to whichever value is most likely to be the result.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
4

There is no difference.

The x86 CPU architecture has two opcodes for conditional jumps

JNE (jump if not equal)
JE (jump if equal)

Usually they both take the same number of CPU cycles.

And even when they wouldn't, you could expect the compiler to do such trivial optimizations for you. Write what's most readable and what makes your intention more clear instead of worrying about microseconds.

Philipp
  • 67,764
  • 9
  • 118
  • 153
  • Very specific to x86 and does not take into account the fact that the instruction cache is warmer for the first block (though which block the *compiler* places first is not evident). – Matthieu M. Dec 12 '12 at 13:50
4

If you ever manage to write a piece of Java code that can be proven to be significantly more efficient one way than the other, you should publish your result and raise an issue against whatever implementation you observed the difference on.

More to the point, just asking this kind of question should be a sign of something amiss: it is an indication that you are focusing your attention and efforts on a wrong aspect of your code. Real-life application performance always suffers from inadequate architecture; never from concerns such as this.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
2

Early optimization is the root of all evil

Even for branch prediction, I think you should not care too much about this, until it is really necessary.

Just as Peter said, use the simplest way.

sleepsort
  • 1,321
  • 15
  • 28
  • 3
    @MarkoTopolnik: The really correct quote would be "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified " since it changes meaning quite a lot with that necessary context missing. – PlasmaHH Dec 12 '12 at 12:54
  • @PlasmaHH What do you mean? It just explains the obvious common wisdom implied by the punchline version: first profile, then optimize. – Marko Topolnik Dec 12 '12 at 12:59
  • 1
    @MarkoTopolnik: I see the punchline version most of the time abominized to "write something that works ignoring all optimization opportunities (both in overall design and local optimizations) and after someone complains that it is too slow try to find some single spot you might want to optimize" – PlasmaHH Dec 12 '12 at 13:09
  • @PlasmaHH Talking from my experience on StackOverflow, I never saw that interpretation. People tend to optimize prematurely with no clear focus and are advised to concentrate on overall architecture and optimize only after profiling. – Marko Topolnik Dec 12 '12 at 13:23
  • @MarkoTopolnik My experience is more like PlasmaHH's. Some people plaster that catch-phrase even where people ask for algorithmic improvements, not only where people wonder whether some bit twiddling would shave off a cycle or two for the whole programme. Although here on SO, you have a higher percentage of people using it in an appropriate way than in the rest of the internets. – Daniel Fischer Dec 12 '12 at 15:01
  • @DanielFischer True, I can remember such experience from elsewhere. Somehow I can't make myself see turning O(n^2) into O(n) an *optimization*, though: I see it as plain *correction* :) But yes, I see your point. – Marko Topolnik Dec 12 '12 at 15:05
  • @MarkoTopolnik "Somehow I can't make myself see turning O(n^2) into O(n) an _optimization_, though: I see it as plain _correction_", I tend to agree, although that destroys the other adage, "the most efficient optimisation is to choose a better algorithm". – Daniel Fischer Dec 12 '12 at 15:17
  • @DanielFischer The line is blurry, that's for sure. Another example is redesigning messy GUI code where the same event ends up handled 10 or more times. The result is faster code so some could argue it was optimized; I'd say it was plain *fixed*. – Marko Topolnik Dec 12 '12 at 15:21
2

Let the compiler/optimizer do its work. It's a general rule of thumb (most nowadays) that the source code should express your intention in the most readable way. You are writing it to another human (and not to the computer), the one year later yourself or your team mate who will need to understand your code with the less effort.

Big J. Lee
  • 53
  • 7
1

It shouldn't make any difference performance wise but you consider what is easiest to read. Then when you are looking back on your code or if someone is looking at it, you want it to be easy to understand.

Duane
  • 1,980
  • 4
  • 17
  • 27
0

it has a little advantage (from point of readability) if the first condition is the one that is true in most cases. Write the conditions that way that you can read them best. You will not benefit from speed by negating a condition

AlexWien
  • 28,470
  • 6
  • 53
  • 83
0

Most processors use an electrical gate for equality/inequality checks, this means all bits are checked at once. Therefore it should make no difference, but you want to truly optimise your code it is always better to benchmark things yourself and check the results.
If you are wondering whether it's worth it to optimise like that, imagine you would have this check multiple times for every pixel in your screen, or scenarios like that. Imho, it is alwasy worth it to optimise, even if it's only to teach yourself good habits ;)

Kevin
  • 2,739
  • 33
  • 57
0

Only the non-negative approach which you have used at the first seems to be the best .

muthukumar
  • 2,233
  • 3
  • 23
  • 30
0

The only way to know for sure is to code up both versions and measure their performance. If the difference is only a percent or so, use the version that more clearly conveys the intent.

It's very unlikely that you're going to see a significant difference between the two.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Performance difference between them is negligible. So, just think about readability of the code. For readability I prefer the one which has a more lines of code in the If statement.

if (a == x) { 
    // x lines of code
} else {
    // y lines of code where y < x
}
Parvin Gasimzade
  • 25,180
  • 8
  • 56
  • 83