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?
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.