Existe-t-il une raison de performance pour déclarer les paramètres de méthode définitifs en Java?

117

Existe-t-il une raison de performance pour déclarer les paramètres de méthode définitifs en Java?

Un péché:

public void foo(int bar) { ... }

Contre:

public void foo(final int bar) { ... }

En supposant que ce barn'est que lu et jamais modifié dans foo().

Kip
la source
Je ne peux pas penser à une raison pour laquelle le compilateur se soucierait si vous déclariez un paramètre de méthode final ou non. Mais la vraie réponse à cette question est - écrivez deux fonctions, une avec des paramètres finaux et une avec des paramètres réguliers. Exécutez-les un million de fois chacun et voyez s'il y a une différence d'exécution notable. Si vous êtes préoccupé par les performances, il est très important d'effectuer un travail de profilage sur votre code et de savoir exactement ce qui vous ralentit. Ce n'est certainement pas ce à quoi vous vous attendriez :)
Mike Blandford
1
Je vous suggère de ne jamais écrire de micro-benchmarks. Vous ne savez pas quelle optimisation le JIT peut faire et quand, et vous auriez probablement une mauvaise idée de la façon dont il se comporte simplement en faisant un "cas de test simple"
Edmondo1984
Eh bien c'est peut-être, mais personne ici n'a écrit ou suggéré un microbenchmark ...
Kip
1
La réponse de @Mike Blandford suggère d'utiliser un micro-benchmark n'est-ce pas?
Ben Page
Écrire des micro-benchmarks en Java est quelque chose de très très délicat
Edmondo1984

Réponses:

97

Le mot-clé final n'apparaît pas dans le fichier de classe pour les variables et paramètres locaux, il ne peut donc pas affecter les performances d'exécution. Son seul usage est de clarifier l'intention des codeurs que la variable ne soit pas modifiée (ce que beaucoup considèrent comme une raison douteuse pour son utilisation) et de traiter des classes internes anonymes.

Il y a beaucoup d'arguments pour savoir si le modificateur final de la méthode elle-même a un gain de performance puisque les méthodes seront de toute façon incorporées par le compilateur d'optimisation au moment de l'exécution, quel que soit le modificateur. Dans ce cas, il ne doit également être utilisé que pour restreindre le remplacement de la méthode.

Robin
la source
5
on pourrait penser que les variables / paramètres finaux pourraient être optimisés en tant que variables de boucle cependant ... mais un bon compilateur / runtime devrait être capable de comprendre cela sans fin de toute façon ...
John Gardner
9
J'ai vu le compilateur de Sun émettre un bytecode légèrement plus court alors que la seule différence entre les deux méthodes était la "finalité" des variables locales. Les micro-optimisations sont une chose réelle, et les compilateurs les font réellement. Ce qui compte vraiment, bien sûr, c'est ce que le JIT fait avec le bytecode, et les références locales perdent leur "finalité" lorsqu'elles sont compilées en bytecode. Je pense que c'est la raison pour laquelle il y a tant de spéculations sur les variables locales finales: les résultats sont tout à fait non déterministes. Cependant, l'utilisation des paramètres locaux finaux peut affecter le bytecode - pour ce qu'il vaut.
Christopher Schultz
Comme il n'est pas déterministe, il n'y a vraiment aucun moyen de dépendre de l'optimisation non plus. Bien sûr, beaucoup de choses ont peut-être changé dans les implémentations de VM depuis la réponse initiale en 2008 ;-)
Robin
15

Le seul avantage d'un paramètre final est qu'il peut être utilisé dans des classes imbriquées anonymes. Si un paramètre n'est jamais modifié, le compilateur le détectera déjà dans le cadre de son fonctionnement normal, même sans le modificateur final. Il est assez rare que les bogues soient causés par un paramètre assigné de manière inattendue - si vos méthodes sont suffisamment grandes pour nécessiter ce niveau d'ingénierie, réduisez-les - les méthodes que vous appelez ne peuvent pas modifier vos paramètres.

Dobes Vandermeer
la source
8
"Il est assez rare que des bogues soient causés par un paramètre assigné de manière inattendue". C'est plus courant que vous ne le pensez ...
RAY
2
@RAY vous avez peut-être raison, en fait je n'ai aucune donnée (au-delà de ma propre expérience) pour étayer cette affirmation.
Dobes Vandermeer
@DobesVandermeer pour être plus précis, ce n'est pas vraiment un "avantage pour un paramètre final ". Ce que vous décrivez est simplement la syntaxe requise pour que toutes les variables locales (dont j'inclus les paramètres) soient rendues visibles dans la portée locale de la classe imbriquée anonyme.
swooby
0

Les compilateurs qui fonctionnent après le chargement de classe, tels que les compilateurs JIT, peuvent tirer parti des méthodes finales. Par conséquent, les méthodes déclarées définitives pourraient avoir des avantages en termes de performances.

http://www.javaperformancetuning.com/tips/final.shtml

Oh et une autre bonne ressource

http://mindprod.com/jgloss/final.html

branchegabriel
la source
10
La question concernait les paramètres déclarés définitifs, ce qui n'a aucun impact sur les performances.
Robin
La finale du JIT'S (Hotspot) moderne n'a aucune influence (mesurable) sur les performances, qu'elle soit appliquée aux paramètres ou à la classe
kohlerm
2
Les deux articles que vous liez suggèrent tous deux que final est plutôt une marque sémantique pour les développeurs, et que les compilateurs JIT peuvent utiliser final (mais comme d'autres l'ont souligné, ils n'ont pas vraiment besoin de cette information). Donc final est plutôt sémantique, ce qui est en parallèle avec la capacité des compilateurs C / ++ modernes à déduire la constance des variables et des méthodes même si elles ne sont pas marquées explicitement const.
ron
0

Juste un point de plus, au-dessus de l'utilisation de variables locales non finales déclarées dans la méthode - l'instance de classe interne peut survivre au cadre de la pile, de sorte que la variable locale peut disparaître tant que l'objet interne est toujours en vie

utilisateur666
la source
-2

Je suppose que le compilateur pourrait éventuellement supprimer toutes les variables finales statiques privées qui ont un type primitif, tel que int, et les incorporer directement dans le code, comme avec une macro C ++.

Cependant, je n'ai aucune idée si cela est fait dans la pratique, mais cela pourrait être fait afin d'économiser de la mémoire.

user1402866
la source
La question ne concerne pas les variables finales des statistiques privées.
Marquis of Lorne