2009-03-15 4 views
25

Y at-il une pénalité pour avoir appelé newInstance() ou est-ce le même mécanisme en dessous? Quel est le surcoût éventuel de newInstance() par rapport au nouveau mot-clé *?newInstance() vs new

*: En ne tenant pas compte du fait que newInstance() implique l'utilisation de la réflexion.

Répondre

15

Dans un test du monde réel, créer 18129 instances d'une classe via "Constuctor.newInstance" en passant 10 arguments -vs- créer les instances via "nouveau" le programme n'a pas pris de différence mesurable dans le temps.

Ce n'était pas une sorte de micro-benchmark.

Ceci est avec JDK 1.6.0_12 sous Windows 7 x86 bêta. Étant donné que Constructor.newInstance va être très similaire à Class.forName.newInstance, je dirais que l'overhead est à peine quelque chose étant donné la fonctionnalité que vous pouvez obtenir en utilisant newInstance par rapport à new.

Comme toujours, vous devriez le tester vous-même pour voir.

+1

Consultez http://www.ibm.com/developerworks/java/library/j-jtp02225.html ... ces types de benchmarks sont très difficiles à obtenir en raison de la manière dynamique dont le code est compilé/optimisé par le JVM. – Eddie

+0

Comme je l'ai dit, c'était un exemple du monde réel, pas un micro benchmark ... – TofuBeer

1

Méfiez-vous des microbenchmarks, mais j'ai trouvé this blog entry où quelqu'un a trouvé que new était environ deux fois plus rapide que newInstance avec JDK 1.4. Il semble qu'il y ait une différence, et comme prévu, la réflexion est plus lente. Cependant, il semble que la différence ne soit pas un dealbreaker, en fonction de la fréquence des nouvelles instances d'objets et de la quantité de calcul effectuée.

+0

La réflexion a gooten plus rapide avec chaque version de Java. – TofuBeer

+0

Oui, en effet, c'est pourquoi j'ai mentionné l'utilisation de 1.4 dans le cas-test que j'ai trouvé. Je suis sûr que newInstance est encore plus lent, mais je serais surpris si c'était une énorme différence. – Eddie

+0

Appeler setAccessible (true) sur le constructeur devrait le rendre légèrement plus rapide (mais assurez-vous toujours sécurisé). Bien sûr, je suggère d'éviter la réflexion si possible dans tous les cas. –

-1

Il y a une différence - en 10 fois. La différence absolue est minime, mais si votre application écrit à faible latence, le temps processeur cumulé perdu peut être significatif.

long start, end; 
    int X = 10000000; 
    ArrayList l = new ArrayList(X); 
    start = System.nanoTime(); 
    for(int i = 0; i < X; i++){ 
     String.class.newInstance(); 
    } 
    end = System.nanoTime(); 
    log("T: ", (end - start)/X); 

    l.clear(); 
    start = System.nanoTime(); 
    for(int i = 0; i < X; i++){ 
     new String(); 
    } 
    end = System.nanoTime(); 
    log("T: ", (end - start)/X); 

Sortie:

T: 105 
T: 11 

Testé sur Xeon W3565 @ 3.2Ghz, Java 1.6

+3

Je regarderais attentivement ce code. Pendant l'exécution, l'optimiseur java arrêtera simplement d'exécuter new String() car il peut le faire sans avoir d'effets secondaires. Il ne fera pas la même chose pour String.class.newInstance() car il s'agit d'une réflexion et il ne peut pas dire si la classe factory newInstance a des effets secondaires. – cmdematos

Questions connexes