-2

For example I have 3 calls of one method (always 3 calls) and I need to pass 1 to method for the first call 2 for the second and 3 for the third. I can solve that Problem in 2 ways. Either make 3 calls with 1, 2, 3 or use a for loop.

call(1);
call(2);
call(3);

for (int i = 1; i <= 3; i++) {
    call(i);
}

The question is what will run faster. As I know this depends completly on the Java Compiler, because it could make optimizations on the for loop.

In plain C the redundant way would be a little bit faster I guess, because there is no counter needed to increment and compare.

HenrikD
  • 241
  • 2
  • 10
  • why do you care about performance in this specific case? and if you wanted to call the method 100 times what would you do? – Ousmane D. Mar 10 '18 at 11:21
  • If the calls are independent from each other it would probably be the fastest to run them in parallel. – maraca Mar 10 '18 at 11:23
  • I think the difference is less than 1ms so why care about ? – azro Mar 10 '18 at 11:23
  • 2
    It doesn't depend on the compiler. It depends on the JIT (which could unroll the loop if it finds that helpful). Strive for correctness, readability and maintainability. Copy and pasting instructions to avoid a loop in hope of a better performance is a really bad idea: you'll introduce bugs (like forgetting to increment the value), make the code less readable and maintainable, and you won't gain any significant improvement in terms of performance. – JB Nizet Mar 10 '18 at 11:32

2 Answers2

2

There is no definite answer to this. It will depend on the version of Java that you use, the platform that you run it on, how often you run it (e.g. whether the code is JIT compiled or not), and so on.

However, we can say that even if the JIT compiler optimizer doesn't unroll the loop, the difference in execution times between the two versions will only be a few nanoseconds on a modern CPU. This is unlikely to make a noticeable difference to the overall performance of your application.

My advice would be to not spend time trying to make your code faster at this level.

  • Spend your time getting it to work.
  • Once it is working, benchmark it and decide if it is fast enough.
  • If and only if it is not fast enough:
    1. use a profiler to find the hotspots
    2. optimize a hotspot
    3. rerun the benchmark to decide if your optimization helped
    4. repeat ... until you run out of hotspots to look at, or it is fast enough.
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

I am assuming that by "redundant" you mean that instead of a loop you manually write out all function calls.

In terms of efficiency - yes, the redundancy is inefficient, but not for the reason you might think. It is inefficient in terms of maintenance cost and in terms of code/file size bloat.

For example, you have 3 function calls right now with 3 integers. Later you might decide you need to instead call it 20 times, and with the redundant method this involves copying the line 17 extra times with new integers.

Now you decide that the integers you are currently passing in need to be changed. As a result, you have to update all 20 integers.

Next you decide you need to insert some logic between each function call, so you write it once and copy+paste it 20 times.

This scales extremely poorly, increases the size of the file (byte size), and is error-prone. If it turns out the logic you added between the functions had a bug, you now have the same bug in 20 different places to fix.

Any speedups you would gain will likely be negated down the line because your code has become a horrible, un-maintainable monster.


What you might want to look into instead is a more limited form of this called loop unrolling. This can be done both by hand and, as pointed out in the comments, by the JIT compiler if it determines that it is actually worth it. It targets the issue you raise with the for loop having both a counter and a logical comparison which introduces some overhead. The idea is that you try to perform as many computations as are reasonable during each loop and perform fewer loops as a result.

Simple Example:

for (int i = 1; i <= 300; i += 3) {
    call(i);
    // some logic
    call(i + 1);
    // some logic
    call(i + 2);
    // some logic
}

Now you call the same function 3 times in the loop and loop 100 times, but 300 function calls result. This is both potentially more efficient than having 1 function call in the loop and it is far more scalable.

Stephano
  • 356
  • 1
  • 5