0

Should I trade code-compactness for a bit of performance? Concretely speaking, which one of the following two is preferable:

// case 0:
final boolean flag = <some condition>;
for (int i = 0; i < SOME_COUNT; ++i)
{
    if (flag)
    {
        // do foo
    }
    else
    {
        // do bar
    }

}

// case 1:
final boolean flag = <some condition>;
if(flag)
{
    for (int i = 0; i < SOME_COUNT; ++i)
    {
        // do foo
    }
}
else
{
    for (int i = 0; i < SOME_COUNT; ++i)
    {
        // do bar
    }
}
One Two Three
  • 22,327
  • 24
  • 73
  • 114
  • 4
    In the words of Donald Knuth _premature optimization is the root of all evil_. Use the first. – Boris the Spider Jun 02 '14 at 19:20
  • 2
    The test is going to cost you a few nanoseconds. Don't duplicate code needlessly until you are _sure_ (i.e. you've measured it and proven it) you have a performance problem. – Jim Garrison Jun 02 '14 at 19:20
  • 1
    Q: `when NOT to factor out common code` / A: When you have not used a profiler to see where time is actually being spent :) It is extremely unlikely that this will make a noticeable difference whatsoever. This way, it becomes a stylistic preference only (hence off-topic). – ChristopheD Jun 02 '14 at 19:23

3 Answers3

5

Prefer the former. For all you know the JIT is able to make the first just as fast as the second.

The rule of thumb with performance: when in doubt, measure. And when you do decide to measure, read this first: How do I write a correct micro-benchmark in Java?

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 5
    Don't confuse JIT with branch prediction. One is software and the other is hardware. In this case, the end result is the same. Since `flag` is constant, it will be easy for the hardware branch predictor to get it right. – Mysticial Jun 02 '14 at 19:22
  • @Mysticial does the term "branch prediction" refer solely to hardware? If so, TIL – and don't hesitate edit my answer to be more accurate with the terminology. When it comes to optimization, I know you know way more than myself. – Matt Ball Jun 02 '14 at 19:27
  • Correct. "Branch Prediction" refers only to the hardware making guesses. To the software (JIT, compiler, programmer), it's just a black box with no direct way to interact with it. (But a JIT/compiler/programmer with knowledge of how the black box works can still influence its behavior by poking it the right way.) – Mysticial Jun 02 '14 at 20:32
4

I'd go for the second option, considering the flag attribute is constant and non volatile.

Why would you spend time checking a condition, you already know the result?

Just check it once at the beginning, and do your thing

Please note that you may also find yourself in the need to perform some operations that depend on the flag value, and need to be executed outside the for loop.

In the second case, it's just as easy as adding a new line inside the condition branch

In the first case, you will need to check the condition AGAIN outside the for loop

Matias Cicero
  • 25,439
  • 13
  • 82
  • 154
  • I don't think that sacrificing readability and conciseness to the gods of performance is right in this case. And [Matt's answer](http://stackoverflow.com/a/24001707/2071828) is correct, even in the worst case the branch predictor would make swift work of this constant `boolean`. – Boris the Spider Jun 02 '14 at 19:48
0

I'd go with option 0. Two things:

  • It's closer to the intention of the code (at least that's how I read your question and, in fact, the code). This will make it easier to maintain the code in the future - it's hard to imagine how much time the change you propose would actually make but I believe the time you save developing will always outscale the savings you'd make by orders of magnitude.
  • Second, Just-in-time compilation means you might not even doing yourself a favor performancewise because the java virtual machine might find out for you if case 1 is actually better and react accordingly.
Nicolas78
  • 5,124
  • 1
  • 23
  • 41