Make Your Java Applications Run Faster - Part 3 - Variables and Arrays
In the previous two parts of the series "Make Your Java Applications Run Faster" we saw how the compiler does some of the optimizations for us and some general techniques that can be applied to our code.
In this section, we shall see how usage of arrays and built in variables can be optimized.
Array Initializations: For optimizing your java code, It is important to know how arrays are initialized. Arrays are initialized at run time one element at a time.
For Example:
int[][] positions = {{0,0},{1,2},{2,5}};
The above array initialization is translated literally by the compiler to the equivalent:
int[][] positions = new int[3][];
positions[0]=new int[2];
positions[0][0] = 0;
positions[0][1] = 0;
positions[1]=new int[2];
positions[1][0] = 1;
positions[1][1] = 2;
positions[2]=new int[2];
positions[2][0] = 2;
positions[2][1] = 5;
This sort of initialization creates the following problems:
1) It can bloat your class files by adding more byte code to the class file.
2) When such array is initialized as a local variable, these se of codes will get executed each time the method is invoked.
It is better to declare the array as a static or instance member to eliminate the initialization for each iteration. Even if you need a fresh copy each time the method is called, for non-trivial arrays it is faster to store a single initialized copy and make a copy of it.
Copying Arrays: You can create a copy of an array efficiently by using the System.arraycopy() method. It is a special purpose optimized native method which is faster and efficient than copying each element in a loop.
Care when using byte, short and char: When stored in a variable, built in types like byte, short, char and boolean all are represented as 32 bit values just like int and also use the same bytecode for loading and storing. The differerence in the memory used comes only when these built in types are stored in arrays. When stored in arrays, boolean and byte values are stored as 8-bit values, while short and char values are stored as 16-bit values.
Note that int, float, and object reference values are always stored as 32-bits each, and long and double values are always stored as 64-bit values.
The fastest types of variables are int and reference variables. This is because all operations on byte, short, and char are performed as ints, and assigning the results to a variable of the corresponding type requires an explicit cast.
In the following, (b + c) is an int value and has to be cast to assign to a byte variable:
byte a, b, c;
a = (byte) (b + c);
Casting requires extra bytecode instructions and thus adds additional overhead when using these smaller types namely byte, short and char.
Thus, the benefit of using smaller types comes only when they are stored in and array and are seldom used in arithmetic operations.