Bonjour,
est ce qu'une utilisation abusive du mot clé final (pour tous les paramètres des méthodes et pour quasiment tous les objets crées) peut dégrader les performances d'une application?
merci pour vos retours d'expérience.
Version imprimable
Bonjour,
est ce qu'une utilisation abusive du mot clé final (pour tous les paramètres des méthodes et pour quasiment tous les objets crées) peut dégrader les performances d'une application?
merci pour vos retours d'expérience.
à moins que je me trompe mais le compilateur optimise final donc à mon sens tant qu'on peut en mettre ....;)
certes je dirais que c'est pas mal, mais je suis curieux de voir une appli ou la majorité des données snont figées au lancement
Quelques remarques :
Le mot clé final ne dégrade pas les perfs, mais au contraire les augmente.
De mon expérience, les compilateurs ne transforment pas tout ce qui est possible en final ; par contre les optimiseurs (genre l'obfuscateur "proguard") oui.
pour BainE : En fait énormement de choses peuvent être déclarées final dans une classe. La plupart des paramètres d'une méthode par exemple. Il ne faut pas oublier que déclarer un objet final n'empèche pas de modifier sa structure interne, mais simplement de le réaffecter.
C'est même dans la FAQ : Que signifie le mot-clé final ? :P.Citation:
Envoyé par June31
+1Citation:
Envoyé par June31
Même si les différences ne sont pas forcément significatives... Toutefois cela permet en plus de garantir que la valeur ne sera pas modifié "accidentellement", ce qui peut prévenir de certains petits bugs...
Toutefois il ne faut pas l'utiliser à tord et à travers et toujours bien avoir en tête les restrictions qu'il impose (et donc l'utiliser à bon escient) :Ainsi on peut utiliser massivement final sans craintes sur les paramètres de méthodes et les variables locales (lorsque cela s'avère utile), car cela ne peut pas avoir d'impact en dehors de notre code...
- Une variable local final ne peut être initialisé qu'une seule et unique fois. Elle peut également être utilisé dans une classe anonyme.
- Un paramètre de méthode final ne peut pas être affecté par le code de la méthode. Il peut également être utilisé dans une classe anonyme.
- Un attribut de classe final ne peut être initialisé qu'une seule et unique fois, en ligne à la déclaration, dans un bloc d'instance, ou dans chaque constructeur de la classe (et en ligne à la déclaration ou dans un bloc static pour les attributs static).
- Une méthode final ne peut pas être redéfini dans une classe fille.
- Une classe final ne peut pas être étendu.
Par contre concernant les attributs de classes, les méthodes et les classes, cela peut poser des problèmes si ce n'est pas adapté à la situation en empechant l'héritage et la redéfinition (en partie ou complètement). Ainsi tous les attributs, méthodes et classes ne peuvent pas forcément être déclaré en final sans imposer des restrictions dans la conception POO (si ces restrictions sont volontaire cela ne pose pas de problèmes bien sûr) !
Enfin à ma connaissance le mot clef final apporte deux types d'optimisation :a++
- Les attributs final peuvent bénéficier d'optimisation aggressive sans poser de problème en environnement multithread (ie : la référence n'est lu qu'une seule fois et n'as pas besoin d'être revérifié à chaque fois car elle ne sera pas modifié).
- Les appels de méthodes final (tout comme les méthodes private d'ailleurs, ou n'importe quel méthode d'une classe final) peuvent être plus rapide car la JVM n'a pas besoin de vérifier l'existence d'une redéfinition dans une classe fille (puisque c'est impossible). Toutefois les JVMs permettent d'optimiser cela à la volée et les méthodes "non-final" peuvent bénéficier des mêmes optimisations sous certaines conditions sans géner une potentiel redéfinition. J'en ai déjà parlé sur ce thread : http://www.developpez.net/forums/sho...44#post1278444
Pour les methodes elle sont "inlinees" au vol, voir Methode inlining dans HotSpot :Citation:
Envoyé par adiGuba
http://java.sun.com/developer/techni...pot/index.html
Et son article dedie :
http://java.sun.com/developer/techni.../inlining.html
Pour les constantes c'est un peu plus complexe : celles dont les valeurs sont fixees en dur et ne sont pas le resultat de l'execution d'une methode sont "inlinees" des la compilation (recopies "en dur" la ou elles sont utilisees) ce qui evite un appel dynamique inutile :
http://www.javaworld.com/javaworld/j...-constant.html
Ce qui ammene le probleme suivant : quand on modifie la valeur d'une constante, il faut recompiler TOUTES les classes qui l'utilise pour progager la nouvelle valeur.Citation:
According to the Java Language Specification, any static final field initialized with an expression that can be evaluated at compile time must be compiled to byte code that "inlines" the field value. That is, no dynamic link will be present[...]
entre parenthèses les enums apportent une alternative agréable pour contourner ce problèmeCitation:
Envoyé par bouye
Oui c'est ce que je montre dans le thread en lien. Elles peuvent également être "dés-inlinées" au vol si besoin (utilisation d'une classe fille qui redéfinit la méthode).Citation:
Envoyé par bouye
Toutefois cela ne concerne que les types primitifs et les String lorsqu'ils sont initialisés en ligne :Citation:
Envoyé par bouye
On peut éviter ce comportement soit en passant par la création d'un objet :Code:
1
2 public static final int X = 5; public static final String S = "Hello World";
Soit en initialisant les champs dans un bloc static :Code:
1
2
3 public static final int X = new Integer(5).intValue(); public static final String S = new String("Hello World").intern(); // Le intern() permet de bénéficier quand même du pool de String
a++Code:
1
2
3
4
5
6 public static final int X; public static final String S; static { X = 5; S = "Hello World !" }
:D
j'avais justement besoin de cette précision
Merci les Modos
@++