3

Does the order of 'if-conditions' impacts the performance?

Under the assumption the order matters this code if (slowMethod() && fastMethod()) would be slower than if (fastMethod() && slowMethod()).

I assume that the order does matter as the compiler does not analyze the execution-time of the conditions. But I'm not sure.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • 6
    the second (right) operand is only evaluated if the first (left) operand is true, so the order matters. – Eran Nov 21 '17 at 09:59
  • It is not much the `fastMethod()` or `slowMethod()` but how fast it is times what it guards against. – Willem Van Onsem Nov 21 '17 at 09:59
  • 3
    `&&` short circuits, so it is definitely possible that `fastMethod() && slowMethod()` will be faster, because `slowMethod()` could be skipped. – khelwood Nov 21 '17 at 09:59
  • https://stackoverflow.com/questions/8759868/java-logical-operator-short-circuiting – tkausl Nov 21 '17 at 10:00
  • @tkausl Shouldn't this be closed as a duplicate? I don't want to decide alone, but I'd vote for it. – maaartinus Nov 21 '17 at 10:10
  • https://stackoverflow.com/questions/8759868/java-logical-operator-short-circuiting differs to this question. This question is about the performance impact, https://stackoverflow.com/questions/8759868/java-logical-operator-short-circuiting is more general. – Manuel Drieschmanns Nov 21 '17 at 10:15

4 Answers4

8

The two conditions will be evaluated in that order, but the second condition will only be evaluated if the the first one is true - so at first sight it may seem better to put fastMethod first.

However from a performance perspective, the order should also take the probability of each expression to be true into account: although fastMethod is faster, if it's almost always true and slowMethod is almost always false, you may want to test slowMethod first.

Example, assume that:

  • fastMethod takes 1 ms, returns true 80% of the time
  • slowMethod takes 3 ms, returns true 10% of the time

then:

  • fastMethod && slowMethod will take 3.4 ms on average (1 ms 20% of the time, 4 ms 80% of the time)
  • slowMethod && fastMethod will take 3.1 ms on average (3 ms 90% of the time, 4 ms 10% of the time)

Finally, the JIT compiler and the CPU are very good at optimising conditions, sometimes leading to counterintuitive performance result. A definite answer to your question can only be obtained by benchmarking/profiling your specific use case.

assylias
  • 321,522
  • 82
  • 660
  • 783
3

The && operator (as well as the || operator) perform shortcircuiting. That means that if you have two operands A and B, and A turns out to be false, then evaluating B makes no sense in A && B: regardless what the value of B is, the result will be false anyway.

But that does not mean you always should put slowMethod() after fastMethod().

Say for instance fastMethod() takes 0.01 seconds, but for 99.9% of the cases, the outcome is true, and slowMethod() takes 1.0 seconds, but is true for 50% of the cases.

Then the fastMethod() && slowMethod() approach will have an average runtime of:

t(fast_slow) == 0.01 + 0.999 * 1.0 = 1.009

Whereas for slowMethod() && fastMethod() approach, we get:

t(slow_fast) = 1.0 + 0.5 * 0.01 = 1.005

Short-circuiting is not only used to boost performance. It can also be used to guard against exceptions in an elegant way. We can for instance use it as:

Object[] data = ...
if (data.length > 2 && data[2] != null) {

}

In case we did it the other way, it could raise an index out of bounds, whereas here the first condition checks if the array has enough elements.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

if (fastMethod() && slowMeothod()) is the faster way of doing it.

For && the expression to the left of the operator is evaluated first, if this is false then the expression will finish, as it knows it does not need to evaluate the right-hand side, this means that you want the expression that is faster to evaluate on the left side of the &&.

If you need both expressions to be evaluated then you can use the & operator which forces both expressions to be evaluated. If you use this one then it does not matter which side of the operator each expression is.

Jonathan Coustick
  • 1,127
  • 9
  • 19
0

Yes, it matters. In some cases, only the first operand(s) is(/are) evaluated. The documentation calls this 'short circuiting'.

The Conditional Operators

The && and || operators perform Conditional-AND and Conditional-OR operations on two boolean expressions. These operators exhibit "short-circuiting" behavior, which means that the second operand is evaluated only if needed.

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

Joost
  • 3,169
  • 2
  • 22
  • 40