412 votes

Utilisation du mot clé final en Java améliore-t-il la performance ?

En Java, on peut voir beaucoup d'endroits où le mot-clé final peut être utilisé, mais nous ne sommes pas habitués.

Pour eg.

String str = "abc";
System.out.println(str);

Dans le cas ci-dessus str peut être définitive, mais nous avons l'habitude de les oublier.

Si la méthode ne va pas être remplacée dans ce cas, on peut utiliser le mot-clé final. Mais généralement, nous n'avons pas. De même dans le cas de la classe qui ne va pas être héritée.

N'utiliser le mot-clé final vraiment améliorer les performances? Si oui, comment? Veuillez expliquer. Si vraiment c'est important dans la performance, alors il devrait être fait comme d'habitude.

325voto

Jon Skeet Points 692016

Généralement pas. Pour les méthodes virtuelles, HotSpot garde une trace de savoir si la méthode a effectivement été remplacés, et est capable d'effectuer des optimisations telles que l'in-lining sur l' hypothèse qu'une méthode n'a pas été remplacé jusqu'à ce qu'il charge une classe qui remplace la méthode, à quel point il peut annuler tout ou en partie, annuler) ces optimisations.

(Bien sûr, c'est en supposant que vous êtes en utilisant HotSpot - mais c'est de loin le plus commun de la JVM, donc...)

À mon avis, vous devez utiliser final basé sur la conception claire et la lisibilité plutôt que pour des raisons de performances. Si vous voulez changer quoi que ce soit pour des raisons de performances, vous devez effectuer les mesures appropriées avant de courber le plus clair du code à partir de la forme de cette façon, vous pouvez décider quel supplément de rendement obtenu en vaut la peine les plus pauvres de la lisibilité/design. (Dans mon expérience, il n'est presque jamais la peine; YMMV.)

EDIT: Comme final champs ont été mentionné, il est intéressant apporter qu'ils sont souvent une bonne idée de toute façon, en termes de design clair. Ils changent aussi la garantie de comportement en termes de cross-thread visibilité: après un constructeur a terminé, la dernière champs sont garantis pour être visible dans les autres threads immédiatement. C'est probablement l'utilisation la plus courante de final dans mon expérience, bien que, en tant que partisan de Josh Bloch "la conception de l'héritage ou d'interdire la" règle de pouce, je devrais probablement utiliser final le plus souvent pour les classes...

114voto

rustyx Points 2722

Lorsque l'on parle de final variables locales garder à l'esprit que l'utilisation du mot-clé final permettra au compilateur d'optimiser le code de manière statique, qui peut dans le résultat final plus rapidement dans le code. Par exemple, la finale de Cordes a + b dans l'exemple ci-dessous sont regroupées de manière statique.

public class FinalTest {

    public static final int N_ITERATIONS = 1000000;

    public static String testFinal() {
        final String a = "a";
        final String b = "b";
        return a + b;
    }

    public static String testNonFinal() {
        String a = "a";
        String b = "b";
        return a + b;
    }

    public static void main(String[] args) {
        long tStart, tElapsed;

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method with finals took " + tElapsed + " ms");

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testNonFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method without finals took " + tElapsed + " ms");

    }

}

Le résultat?

Method with finals took 5 ms
Method without finals took 273 ms

Testé sur Java Hotspot VM 1.7.0_45-b18.

Donc quelle est la réelle amélioration de la performance? Je n'ose pas dire. Dans la plupart des cas, probablement marginal (~270 nanosecondes dans cet essai de synthèse, car la concaténation de chaîne est d'éviter de rare cas), mais dans hautement optimisé utilitaire de code, il peut être un facteur. En tout cas, la réponse à la question est oui, il peut améliorer les performances, mais de façon marginale au mieux.

88voto

mel3kings Points 1201

OUI, il peut. Voici un exemple où l'final d'améliorer les performances:

La compilation conditionnelle est une technique dans laquelle les lignes de code ne sont pas compilées dans le fichier de classe basée sur une condition particulière. Cela peut être utilisé pour enlever des tonnes de débogage de code dans une production de construire.

considérez les points suivants:

public class ConditionalCompile {

  private final static boolean doSomething= false;

    if (doSomething) {
       // do first part. 

    }


    if (doSomething) {
     // do second part. 

    }

    if (doSomething) {     
      // do third part. 
    }

    if (doSomething) {
    // do finalization part. 

    }
}

Par la conversion de la doSomething attribut un attribut final, vous avez dit que le compilateur chaque fois qu'il voit doSomething, il faut le remplacer avec de fausses selon le moment de la compilation des règles de substitution. La première phase du compilateur change le code à quelque chose comme ceci:

public class ConditionalCompile {

  private final static boolean doSomething= false;

    if (false){
       // do first part. 

    }


    if (false){
     // do second part. 

    }


    if (false){
      // do third part. 
    }

    if (false){
    // do finalization part. 

    }
}

Une fois cela fait, le compilateur prend un autre regard sur elle et voit qu'il est inatteignable énoncés dans le code. Puisque vous travaillez avec des produits de haute qualité compilateur, il n'est pas comme tous ces inaccessible octets de codes. Donc, elle les enlève, et on se retrouve avec ceci:

public class ConditionalCompile {


  private static boolean doSomething= false;

  public static void someMethodBetter( ) {

    // do first part. 

    // do second part. 

    // do third part. 

    // do finalization part. 

  }

}

ainsi, en réduisant de façon excessive ou de codes inutiles conditionnelle de la vérification.

38voto

wmitchell Points 1658

Selon IBM - ce n’est pas pour les classes ou méthodes.

http://www.IBM.com/developerWorks/Java/library/j-jtp04223.html

14voto

Leo Holanda Points 755

Pour les variables locales à coup sûr il a certains (peut-être peu) impact.

Cela se compile à 255 octets :

Et cela se compile à 228 octets.

Donc, si vous essayez de produire des petit bytecode, y compris toute sou peu, il aura un avantage quelconque.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X