2016-10-02 3 views
0

Lequel serait le plus rapide et pourquoi?Optimisation de la méthode

public void increment{ 
    synchronized(this){ 
    i++; 
    } 
} 

ou

public synchronized void increment(){ 
    I++; 
} 

Would méthode inline améliorer la seconde option?

+0

Les deux sont une seule et même chose si ce n'est que votre code. – SMA

+2

Avez-vous jeté un coup d'œil au bytecode? – Turing85

+0

Oui, je pense que cette question ne peut être résolue qu'en montrant le bytecode. Je suppose que ce sera pareil, rendant la réponse évidente, mais sans vérifier je ne peux pas être sûr. Aussi, je ne suis pas sûr si JLS exige un certain bytecode spécifique, ou si une bonne réponse vérifie à la fois OpenJDK et le JDK d'Oracle. – hyde

Répondre

1

Il est peu probable que la différence ait de l'importance ou soit visible, mais le deuxième exemple pourrait être plus rapide. Pourquoi? Dans Oracle/OpenJDK, moins le code d'octet utilisé par une méthode est élevé, plus elle peut être optimisée, par ex. inline.

Il existe un certain nombre de seuils pour savoir quand une méthode pourrait être optimisée et ces seuils sont basés sur le nombre d'octets de code d'octet. Le deuxième exemple utilise moins de code octet, il est donc possible qu'il soit optimisé davantage. Une de ces optimisations est l'analyse d'échappement qui pourrait éliminer l'utilisation de synchronized pour l'objet local de thread. Cela le rendrait beaucoup plus rapide. Le seuil pour l'analyse d'échappement est la méthode qui est inférieure à 150 octets (après inlining) par défaut. Vous pouvez voir des cas où la première solution fait la méthode un peu plus de 150 octets et la seconde est un peu moins de 150 octets.

REMARQUE:

  • ne pas écrire le code sur cette base, les différents à la matière trop trivial. La clarté du code est loin, beaucoup plus importante.
  • Si la performance est importante, l'utilisation d'une alternative comme AtomicInteger est susceptible d'être d'un ordre de grandeur plus rapide. (uniformément, pas seulement dans de rares cas)
  • BTW AFAIK les bibliothèques de concurrence utilisent peu de assert instructions, non pas parce qu'ils ne sont pas optimisés mais parce qu'ils comptent encore à la taille du code de byte et ralentissent indirectement leur utilisation en signifiant dans Dans certains cas, le code n'est pas aussi optimal. (Cette affirmation de la mienne devrait avoir une référence, mais je ne pouvais pas le trouver)
+1

Est-ce que l'inlining est vraiment fait au niveau du bytecode? Je pense que c'est seulement matérialisé au niveau de l'assemblée. –

+0

@MarkoTopolnik il inline le code de l'octet avant de le transformer en code de machines. Le code d'octet est le même sur toutes les plateformes et bien compris par les développeurs JVM. Le code machine est différent entre les modèles de CPU et les changements au fil du temps, beaucoup plus difficile pour un optimiseur de logiciel pour travailler avec/transformer je imagine. –

+2

Tout ce que je peux trouver actuellement est 'MaxInlineSize', qui fonctionne avec une seule méthode et' MaxInlineLevel', qui limite la profondeur des appels de méthode. –