1

According to a similar question, and multiple Google searches, declaring or initializing a variable outside or inside a loop "might" be the same in terms of performance.

I am running a computer simulation, and I am trying to optimize the code as much as possible, because it has to run a lot of times and it has multiple inner loops with a lot of iterations.

I am wondering if it worth moving all my variables outside of the loops. I have many variables that "theoretically" are constantly re-declared. I said "theoretically" because I don't know if the the Java compiler actually optimize the code and declare everything at, let's say, the method level.

Basically, what would be more efficient? CodeA or CodeB?

Code A:

private void codeA() {
    double a = 0.0;

    for (int i1 = 0; i < i1_N; i1++ ) {
        // Many other loops
             for (int im = 0; i < im_N; im++ ) {
                 a = 0; // a is used for the first time
                 for (int in = 0; i < in_N; in++ ) {
                     a++; // calculate something with a
                 }
             }
        // close many other loops
    }
}

Code B:

private void codeA() {
    double a;

    for (int i1 = 0; i < i1_N; i1++ ) {
        // Many other loops
             for (int im = 0; i < im_N; im++ ) {
                 a = 0; // a is used for the first time
                 for (int in = 0; i < in_N; in++ ) {
                     a++; // calculate something with a
                 }
             }
        // close many other loops
    }
}

Code C:

private void codeC() {

    for (int i1 = 0; i < i1_N; i1++ ) {
        // Many other loops
             for (int im = 0; i < im_N; im++ ) {
                 double a = 0; // a is used for the first time
                 for (int in = 0; i < in_N; in++ ) {
                     a++; // calculate something with a
                 }
             }
        // close many other loops
    }
}

I am just using the variable a in this example, but the computer simulation uses much more. Most of my variables are primitives (int, double, float). Does it make sense to declare primitives outside of the loop in order to improve performance?

Community
  • 1
  • 1
toto_tico
  • 17,977
  • 9
  • 97
  • 116
  • So you got your test case, why not simply run the test? My suggestion is that (as long as you do not use objects), the results will pretty much stay the same. What really eats time are constructor calls. If you use objects, you might want to recycle as much as possible. – Turing85 Jun 25 '15 at 19:04
  • 1
    You have the code ready, why don't you check the runtimes for, say, 1000000 calls of each function. If differences are big, you'll notice, won't you? – pnadczuk Jun 25 '15 at 19:04
  • 2
    Don't forget to read this: [How do I write a correct micro-benchmark in Java?](http://stackoverflow.com/q/504103) – Tom Jun 25 '15 at 19:05
  • Thanks but I haven't implement the version with variables declared outside the loops. I am asking to see if somebody can hint if I should try to optimize. – toto_tico Jun 25 '15 at 19:09
  • 1
    If there is something to improve in that example, then HotSpot ([Oracle article about JIT](https://docs.oracle.com/cd/E15289_01/doc.40/e15058/underst_jit.htm)) could do that probably better than you. You should try to write clear code, which means, reduce the scope of variables, if possible. (Repost to fix the link) – Tom Jun 25 '15 at 19:18
  • @bl3e Nah, ideone is not a Java microbenchmark, it's just for running the code once - it's a different beast :) – Adam Stelmaszczyk Jun 25 '15 at 19:27
  • Perhaps you can start another SO question regarding the bechmarks. This has very little relevance, if any, with my original question. I need a hint if I should try to implement the optimization to save the time programing a new version of my simulation. I might try the benchmarks after I decide to implement that version. I need information to decide. – toto_tico Jun 25 '15 at 19:34
  • 1
    @toto_tico There is only one way: measure. But to be honest I would be *extremely* surprise if it made a difference at all. – assylias Jun 25 '15 at 19:41
  • 1
    @toto_tico Right, sorry for that. I thought such question may be closed as "asking for a tool/library" or "primary opinion-based". But, in the meantime I'm setting up JMH locally to test your thing, so I may have an answer for you in a while. (It takes more than 5 minutes to me though:)) – Adam Stelmaszczyk Jun 25 '15 at 19:41
  • @AdamStelmaszczyk My bad.I missed later part of the comment.compilr looks to be sort of an online ide(I haven't tried).Btw did you mean a website which could generate jmh tests and produce results? – rakesh99 Jun 25 '15 at 19:48
  • @bl3e Yes, exactly. You just paste the code like OP has given and go. Maybe tweak some benchmark parameters after the test (but the default one should be reasonable for most of the cases). – Adam Stelmaszczyk Jun 25 '15 at 19:54
  • @AdamStelmaszczyk, Coda A and B are different just by the initialization, which I don't know how does it work in Java for primitives (I have this clearer for Objects). All that I know is that in Java you cannot use (compile) a variable that hasn't be initialized, so there might be a difference. I stopped assuming anything with modern compilers. – toto_tico Jun 25 '15 at 20:08

1 Answers1

2

javac will not optimize. Bytecode generated in all the 3 cases is different. (javac Test.java compiles and javap -c Test.class shows the bytecode)

Java Virtual Machine may optimize.

JMH benchmark shows the clear winner:

Benchmark           Mode  Cnt    Score    Error  Units
MyBenchmark.testA  thrpt   20  423.437 ±  6.745  ops/s
MyBenchmark.testB  thrpt   20  337.728 ± 56.363  ops/s
MyBenchmark.testC  thrpt   20  351.419 ± 70.290  ops/s

Units are operations per second, the more the better. Benchmark source code. OpenJDK IcedTea 2.5.4 Java Virtual Machine was used.

So, declaring and initializing variables outside should be the most efficient.

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110