2017-03-24 1 views
0

quelle performance est meilleure?quelle est la performance de code byte java getfield vs invokevirtual

J'ai posé cette question sans test parce que je suis paresseux. Maintenant, après le test, il montre getMethod est légèrement plus rapide que .field

Integer xj = x.getJ();` 

ou

Integer yj = x.j; 

Voici byte code java après que je ne décompiler

L5 { 
    aload1 
    invokevirtual testj/ByteCodeTest getJ(()Ljava/lang/Integer;); 
    astore4 
} 
L6 { 
    aload1 
    getfield testj/ByteCodeTest.j:java.lang.Integer 
    astore5 
} 

Voici le code que je teste:

public void setPoint(){ 
    point=System.currentTimeMillis(); 
    System.out.println("point"+point); 
} 
public void comparePoint(){ 
    long endPoint=System.currentTimeMillis(); 
    System.out.println("endPoint"+endPoint); 
    System.out.println("inteval"+(endPoint-point)); 
} 
int count =2000000000; 
public void test22(){ 
    ByteCodeTest x = new ByteCodeTest(); 
    setPoint(); 
    for(int i=0;i<count;i++){ 
     int yy= x.i+1; 
    } 
    comparePoint(); 
    setPoint(); 
    for(int i=0;i<count;i++){ 
     int yy=x.getI()+1; 
    } 
    comparePoint(); 
} 

est ici la sortie de code:

point1490454906205 

endPoint1490454907447 

inteval1242 

point1490454907448 

endPoint1490454908666 

inteval1218 

Cela signifie getMethod est légèrement plus rapide que .field

+1

Pourquoi? Avez-vous l'intention de choisir l'un plutôt que l'autre pour des raisons de performance? – Kayaman

+2

Si les différences de performance à ce niveau vous importent, vous devriez probablement utiliser un langage de programmation de niveau inférieur plutôt que Java. – ControlAltDel

Répondre

0

Lorsque vous utilisez un getter, vous appelez une fonction qui réduit les performances plutôt que l'accès à un champ. Si vous regardez votre code d'octet dans le premier cas, vous devriez trouver une définition pour getJ qui s'appelle ici.

5

accès sur le terrain est plus rapide qu'un appel de méthode, mais à moins que vous écrivez des performances extrêmement sensibles du code dans une boucle serrée, la décision d'utiliser l'un sur l'autre est la conception, pas la performance.

Ajoutez JIT au mélange et vous pourriez ne pas obtenir tout avantage de l'accès direct au champ.

2

Le bytecode est différent, mais à la fin, le JIT permettra d'optimiser l'accès par le getter inline. Contrairement au programmeur au moment de l'écriture du code, le JIT peut dire à tout moment si le getter est écrasé ou non. Faites confiance au JIT sur celui-ci, la performance est identique à long terme.

Ce qui est pas identique, est la maintenabilité. L'utilisation d'une méthode getter vous permet d'écraser le getter avec une logique étendue/modifiée (le prix pour cela rendra le getter polymorphe, induisant une petite pénalité de performance, d'un autre côté cela ne serait même pas possible avec un accès direct au champ).

Utilisation de l'accès direct aux champs vous obtient aucun avantage, mais beaucoup de pièges lorsque le code évolue plus tard.