What is better: multiple "if" statements or one "if" with multiple conditions?

JavaOptimizationIf StatementMultiple Conditions

Java Problem Overview


For my work I have to develop a small Java application that parses very large XML files (~300k lines) to select very specific data (using Pattern), so I'm trying to optimize it a little. I was wondering what was better between these 2 snippets:

if (boolean_condition && matcher.find(string)) {
    ...
}

OR

if (boolean_condition) {
    if (matcher.find(string)) {
        ...
    }
}

Other details:

  • These if statements are executed on each iteration inside a loop (~20k iterations)
  • The boolean_condition is a boolean calculated on each iteration using an external function
  • If the boolean is set to false, I don't need to test the regular expression for matches

Thanks for your help.

Java Solutions


Solution 1 - Java

One golden rule I follow is to "Avoid Nesting" as much as I can. But if it is at the cost of making my single if condition too complex, I don't mind nesting it out.

Besides you're using the short-circuit && operator. So if the boolean is false, it won't even try matching!

So,

if (boolean_condition && matcher.find(string)) {
    ...
}

is the way to go!

Solution 2 - Java

The following two methods:

public void oneIf(boolean a, boolean b)
{
    if (a && b)
    {	
    }
}

public void twoIfs(boolean a, boolean b)
{
    if (a)
    {
        if (b)
        {		
        }
    }
}

produce the exact same byte code for the method body so there won't be any performance difference meaning it is purely a stylistic matter which you use (personally I prefer the first style).

Solution 3 - Java

Both ways are OK, and the second condition won't be tested if the first one is false.

Use the one that makes the code the more readable and understandable. For just two conditions, the first way is more logical and readable. It might not be the case anymore with 5 or 6 conditions linked with &&, || and !.

Solution 4 - Java

Java uses short-circuiting for those boolean operators, so both variations are functionally identical. Therefore, if the boolean_condition is false, it will not continue on to the matching

Ultimately, it comes down to which you find easier to read and debug, but deep nesting can become unwieldy if you end up with a massive amount of braces at the end

One way you can improve the readability, should the condition become longer is to simply split it onto multiple lines:

if(boolean_condition &&
   matcher.find(string))
{
    ...
}

The only choice at that point is whether to put the && and || at the end of the previous line, or the start of the current.

Solution 5 - Java

I recommend extracting your expression to a semantically meaningful variable and then passing that to your evaluation. Instead of:

if (boolean_condition && matcher.find(string)) { ... }

Assign the expression to a variable, then evaluate the variable:

const hasItem = boolean_condition && matcher.find(string)

if (hasItem) { ... }

With this method, you can keep even the most complex evaluations readable:

const hasItem = boolean_condition && matcher.find(string)

const hasOtherThing = boolean_condition || boolean_condition

const isBeforeToday = new Date(string) < new Date()

if (hasItem && hasOtherThing && isBeforeToday) { ... }

Solution 6 - Java

The first one. I try to avoid if nesting like that, i think it's poor style/ugly code and the && will shortcircuit and only test with matcher.find() if the boolean is true.

Solution 7 - Java

I tend to see too many && and || strung together into a logic soup and are often the source of subtle bugs.

It is too easy to just add another && or || to what you think is the right spot and break existing logic.

Because of this as a general rule i try not to use either of them to avoid the temptation of adding more as requirements change.

Solution 8 - Java

If you like to be compliant to Sonar rule squid:S1066 you should collapse if statements to avoid warning since it states:

> Collapsible "if" statements should be merged

Solution 9 - Java

In terms of performance, they're the same.

  • But even if they weren't

what's almost certain to dominate the time in this code is matcher.find(string) because it's a function call.

Solution 10 - Java

Most would prefer to use the below one, because of "&&".

if (boolean_condition && matcher.find(string)) {
...
}

We normally called these as "short-circuit (or minimum evaluation)". It means the 2nd argument (here it is "matcher.find(string)") is only evaluated only if the 1st argument doesn't have sufficient information to determine the value of the expression. As an example, if the "boolean_condition" is false, then the overall condition must be false (because of here logical AND operator). Then compiler won't check the 2nd argument which will cause to reduce the running time of your code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question3rgoView Question on Stackoverflow
Solution 1 - JavaadarshrView Answer on Stackoverflow
Solution 2 - JavaJonathanView Answer on Stackoverflow
Solution 3 - JavaJB NizetView Answer on Stackoverflow
Solution 4 - JavaFarrellView Answer on Stackoverflow
Solution 5 - Java55 CancriView Answer on Stackoverflow
Solution 6 - JavaRobby PondView Answer on Stackoverflow
Solution 7 - Javasm14View Answer on Stackoverflow
Solution 8 - JavaPetter FribergView Answer on Stackoverflow
Solution 9 - JavaMike DunlaveyView Answer on Stackoverflow
Solution 10 - JavaTTDSView Answer on Stackoverflow