IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

[PMD] Règle sur l'utisation de final


Sujet :

Langage Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut [PMD] Règle sur l'utisation de final
    Bonjour,
    J'utilise PMD pour faire un contrôle qualité de mon code. Je m'interroge sur l'utilité de deux règles :
    • MethodArgumentCouldBeFinal
    • LocalVariableCouldBeFinal

    Je comprends bien que le mot-clé final permet d'optimiser l'exécution du code. Je l'utilise dès que possible pour mes attributs.
    Est-ce que l'application de cette règle optimise réellement l'exécution de mon code ou est-ce juste une question de bonnes pratiques ?

    Je me pose la question, vu que je dois avoir à peu près 1000 warnings de ce type

    merci d'avance pour vos réponses.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut
    Re-bonjour,
    comme je suis un grand garcon, j'ai essayé de répondre moi-même à la question.
    J'ai écrit le programme de test suivant :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public class FinalTest {
     
     
    	public FinalTest() {
    		super();
    	}
     
    	public int foo1(int n) {
    		int l=50;
    		return Math.abs(n-l);
    	}
     
    	public int foo2(final int n) {
    		final int l=-50;
    		return Math.abs(n-l);
    	}
     
    	public static void main(String[] args) {
    		int n=1000000000;
    		FinalTest test=new FinalTest();
    		long time1=-System.currentTimeMillis();
    		for (int i = 0; i < n; i++) {
    			test.foo1(-100);
    		}
    		time1+=System.currentTimeMillis();
    		System.out.println("without final : "+time1+" ms");
     
    		long time2=-System.currentTimeMillis();
    		for (int i = 0; i < n; i++) {
    			test.foo2(-100);
    		}
    		time2+=System.currentTimeMillis();
    		System.out.println("with final : "+time2+" ms");
     
    	}
    }
    En effet, cela semble avoir une influence :
    without final : 1146 ms
    with final : 1020 ms

    J'ai donc une nouvelle question. Pourquoi ?

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Février 2006
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 116
    Points : 128
    Points
    128
    Par défaut
    Salut,
    Je vais peut etre dire une connerie mais je pense que la jvm doit optimiser ton code, sachant que ton attribut et final. Ca doit comme const en c.
    D'ailleurs si tu declares ta vairable final static l en dehors de ta fonction tu gagnes en perf.
    Par contre le fait declarer un parametre de la methode final ne doit pas forcement te faire gagner.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut
    Citation Envoyé par MooGle
    Par contre le fait declarer un parametre de la methode final ne doit pas forcement te faire gagner.
    J'ai testé aussi avec juste le paramètre de la méthode en final, il y a aussi un gain. Donc, les règles PMD optimizations.xml sont bien utiles même si elles pourrissent eclipse avec plein de warnings.\\
    Merci pour ton explication, je me doutais qu'il s'agissait dd'une optimisation lors de la compilation ou lors de l'exécution par la JVM, mais je suis curieux de savoir comment elle procède.

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par nono_31 Voir le message
    Merci pour ton explication, je me doutais qu'il s'agissait dd'une optimisation lors de la compilation ou lors de l'exécution par la JVM, mais je suis curieux de savoir comment elle procède.
    Il y a en effet 2 cas que l'on distingue dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	public int foo2(final int n) {
    		final int l=-50;
    		return Math.abs(n-l);
    	}
    Comme la variable "l" est un type primitif final, le compilateur s'authorise à remplacer la variable par sa valeur dans le programme, ce qui revient en fait à faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	public int foo2(final int n) {
    		return Math.abs(n+50);
    	}
    Il y a une variable en moins à manipuler...

    Mieux si tu manipules plusieurs de ces variables, les opérations pourront être effectué dès la compilation autant que possible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    final int a = 50;
    final int b = a*2;
    final int c = (a + b) / 2;
    System.out.println("Résultat : " + c);
    Ce qui sera en réalité compilé comme l'équivalent du code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("Résultat : 75");
    En utilisant final tu indiques au compilateur que la variable ne sera pas modifiée, et il peut donc effectué certaines opérations à l'avance comme de toute manière le résultat sera le même



    Le second cas correspond à l'utilisation de final sur des Object (autre que String) ou des paramètres. Dans ce cas là le compilateur ne peut pas faire grand chose :
    • Pour les objets le final indique seulement que la référence n'est pas modifiable, mais la valeur de l'objet pourrait être modifié...
    • Quand à la valeur des paramètres, elle ne peut pas être connu avant l'exécution, ce qui est plutôt logique !


    Mais lors de l'exécution la JVM peut effectuer des optimisations afin d'éviter de lire la valeur en mémoire plusieurs fois puisque elle sait que sa valeur ne sera pas changé





    Ces optimisations peuvent (ou pourraient) être effectué malgré l'absence du mot-clef final, mais cela neccessite une analyse un peu plus poussé du code (car sans le mot-clef final rien ne garantit que la variable n'est pas modifié un peu plus loin).



    A l'inverse, on peut utiliser volatile pour forcer la JVM à relire la valeur d'une variable en mémoire et de ne pas faire ce type d'optimisation, par exemple lorsque sa valeur est modifié depuis un autre thread



    Il doit bien sûr y avoir d'autre types d'optimisations, mais grosso modo en donnant plus d'info au couple compilateur/JVM il pourra mieux optimiser le code


    Mais la différence n'est pas si énorme que cela lorsqu'on se reporte à un appel : 100ms / 1000000000 ca fais pas beaucoup


    a++

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut
    Merci beaucoup pour ta réponse détaillée et précise.

    Ne t'inquiètes pas, je ne compte pas utiliser ceci dans tout mon code mais uniquement dans certaines parties critiques au niveau de l'efficacité du code.\\
    En fait, le contexte est la programmation de contraintes globales pour un solveur de Programmation Par Contraintes] (Un peu de pub )
    C'est donc des parties de code qui peuvent être appelées un nombre exponentiel de fois (en théorie, bien sûr).
    Du coup, même si ca ne change rien à la complexité, il me semble que cela peut être utile puisqu'il s'agit juste d'une habitude à prendre pour le code critique.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. règle sur blockage d'image
    Par nocoment dans le forum E-Mailing
    Réponses: 4
    Dernier message: 07/11/2009, 03h22
  2. Formater clé réglée sur "booster mémoire"
    Par yo_haha dans le forum Composants
    Réponses: 3
    Dernier message: 01/08/2009, 15h35
  3. [OL-2007] Règle sur boîte commune
    Par Jean-Philippe André dans le forum Outlook
    Réponses: 3
    Dernier message: 30/06/2009, 15h05
  4. Règle sur les Index
    Par dorian53 dans le forum Administration
    Réponses: 31
    Dernier message: 03/11/2006, 07h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo