Bonjour à tous

Dans ma dernière mission, tout le monde avait coché dans les préférences d'Eclipse l'ajout automatique du mot clé "final" partout où c'est possible dans le code. Autre mission autre mœurs, dans l'actuelle les gens ne font pas particulièrement usage du mot clé "final" à part pour déclarer des constantes statiques. J'en ai discuté un petit peu, j'ai creusé sur internet mais c'est flou, la plupart des gens ont l'air de dire que ça peut servir pour la lisibilité mais sans impacter la performance du code.

Et puis on m'a dit aussi que le compilateur de nos jours est très évolué, qu'il détecte tout seul à la compilation que les variables sont modifiées ou non et qu'il insère toujours le mot clé final lorsqu'il voit que c'est possible.

J'ai donc réalisé quelques petits tests pour en avoir le cœur net:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
package final_effectiveness;
 
public class AvecFinal {
	public static String test() {
		final String a = "1";
		final int ba = 2;
		final long bab = 991909000000L;
		return (a + ba + bab);
	}
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
package final_effectiveness;
 
public class SansFinal {
	public static String test() {
		String a = "1";
		int ba = 2;
		long bab = 991909000000L;
		return (a + ba + bab);
	}
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package final_effectiveness;
 
public class Bench {
	private static final int NBL = 999555;
 
	public static void main(final String[] args) {
		long t1, t2;
 
		t1 = System.currentTimeMillis();
		for (int i = 0; i < NBL; i++) {
			AvecFinal.test();
		}
		System.out.println("avec final: " + (System.currentTimeMillis() - t1));
 
		t2 = System.currentTimeMillis();
		for (int i = 0; i < NBL; i++) {
			SansFinal.test();
		}
		System.out.println("sans final: " + (System.currentTimeMillis() - t2));
 
	}
 
}
Première constatation, la taille des fichiers compilés est différente:
502 octets pour AvecFinal.class
760 octets pour SansFinal.class
Ainsi le fait de rajouter des mots clé "final" dans le source aboutit paradoxalement à un bytecode plus léger.

Ensuite le bench:
compliance 1.5, mode debug
avec final: 16
sans final: 328

compliance 1.7 mode prod (NBL passé à 99955566)
avec final: 47
sans final: 23369
Je constate que l'exécution a été 20 fois plus rapide dans le cas où j'ai ajouté les mots clé "final" par rapport à l'autre (500 fois en jdk 1.7 sans les flags de debug)
Tout ceci me porte à conclure que non le compilateur n'est pas aussi magique qu'on le croit, et que dans le cas général l'usage du mot clé final permet vraiment un (petit) gain de performances.

Je souhaiterai cependant avoir votre retour sur cette question, est-ce que j'ai raison ou est-ce que je me suis planté quelque part?