So, I ran some tests on different data structures and noticed that when I declared my final variables, I got 10-20% performance.
It really surprised me. I thought the last keyword was purely used to limit changes in variables, and optimization would determine if any variable has a constant value or not.
Here is an example:
import javafx.scene.input.KeyCode;
import java.util.*;
public class Main {
static int LOOPS = Integer.MAX_VALUE / 100;
static KeyCode[] keyCodes = KeyCode.values();
public static void main(String[] args) {
long startTime;
long endTime;
testEnumSet();
startTime = System.nanoTime();
testEnumSet();
endTime = System.nanoTime();
System.out.println(" EnumSet: " + (endTime - startTime) + "ns");
}
static EnumSet<KeyCode> enumSet = EnumSet.noneOf(KeyCode.class);
static void testEnumSet() {
for (int i = 0; i < LOOPS; i++) {
KeyCode add = getRandomKeyCode();
if(!enumSet.contains(add)) enumSet.add(add);
KeyCode remove = getRandomKeyCode();
if(enumSet.contains(remove)) enumSet.remove(remove);
}
}
static Random random = new Random();
static KeyCode getRandomKeyCode() {
return keyCodes[random.nextInt(keyCodes.length)];
}
}
In the finals: .... EnumSet: 652 266 207ns
Without a finale:EnumSet: 802 121 596ns
It is constantly reproduced!
Why is there such a huge difference between code that uses final and code that doesn't? Why is it not optimized? And why, in any case, finally faster, what is the difference in the generated bytecode?