2016-04-08 2 views
1
int i = 0; 
i += 1; 
i = i + 1; 

Quelle est la différence entre ces 2 options? Quels changements dans les termes de temps de performance? Quel est le plus puissant?Analyser la différence entre i + = 1 et i = i + 1

+5

http://stackoverflow.com/questions/29179528/ii-i1-and-i-1-which-one-is-faster – Sahi

+0

Obligatoire: le choix entre 'i + = 1' et' i = i + 1' n'aura absolument aucun impact discernable sur la performance d'un programme. Les programmes sont lents parce qu'ils font des choses comme créer des millions d'objets, faire des calculs incroyablement compliqués ou attendre sur les requêtes du serveur. – Radiodef

Répondre

7

+ = fait un casting implicite. Par exemple, cela compilera:

int i = 0; 
i += 1L; 

Et ce ne sera pas:

int i = 0; 
i = i + 1L; 

essayé de compiler les deux extraits avec mon jdk1.8.0_11 sur Windows 8 et voir la différence de bytecode ...

0: iconst_0 
1: istore_1 
2: iinc   1, 1 

pour i += 1 version et:

0: iconst_0 
1: istore_1 
2: iload_1 
3: iconst_1 
4: iadd 
5: istore_1 

pour la version i = i + 1. Donc la conclusion est la suivante: vous pouvez en effet obtenir un bytecode différent (ou non, voir @TDG answer) et des performances différentes, mais la différence est insignifiante par rapport à d'autres frais généraux que vos programmes auront.

+0

Savez-vous comment obtenir ce code au format interne comme IL pour C# et assembleur pour C++? –

+0

@ h.o.m.a.n ajouté à ma réponse –

+0

Etes-vous sûr d'avoir des bytecodes différents? Je reçois le même bytecode pour 'i + = 1',' i + = 1L' et 'i = i + 1' avec jdk1.7.0_79. – TDG

2

Vous devez penser en termes de code d'assembly généré et quel code assemblé est complètement dépendant du compilateur utilisé. Certains compilateurs rendront ces différences inexistantes car elles amélioreront vos déclarations. Cependant, en général ...

i += 1; 

est légèrement plus efficace que ..

i = i + 1; 

parce que l'adresse de "i" est accessible uniquement une fois dans "i + = 1". Il vous évite une opération d'assemblage qui n'est généralement pas un gros problème à moins que votre calcul ne soit effectué à travers de nombreuses itérations. Il en résulte de vous sauver une instruction "mov" d'assemblage.

+1

est-ce vrai? les processeurs ont-ils une opération "+ ="? –

+2

Avez-vous vérifié le code d'octet de ces deux lignes et avez-vous remarqué une différence? – TDG

+0

Je suis d'accord. Je pense que même si les processeurs ont une opération "+ =", alors les compilateurs détecteront probablement "i = i + 1" et utiliseront l'opération "+ =" –

0

i=i+1; il devra charger la valeur de i, ajouter un à, puis stocker le résultat à i

i+=1; ajouter un à, puis stocker le résultat

EDIT 1 : certaines personnes disent que la seconde (i + = 1) est plus rapide, mais si vous faites le désassemblage de ce code pièce dans C++ (vs 2013), vous pouvez voir qu'elles sont identiques. Malheureusement, je ne sais pas comment faire cela en JAVA.

i = i + 1; 
00AF52C5 mov   eax,dword ptr [i] 
00AF52C8 add   eax,1 
00AF52CB mov   dword ptr [i],eax 
    i +=1; 
00AF52CE mov   eax,dword ptr [i] 
00AF52D1 add   eax,1 
00AF52D4 mov   dword ptr [i],eax 
+0

bien que ce soit vrai seulement si "ajoutez-y un "est une opération de moins. Qu'est-ce qui te fait penser que c'est? et en fait, même si c'est le cas, alors les compilateurs détecteraient probablement "i = i + 1" et utiliseraient l'opération "+ =" –

+0

@TDG vous avez raison –

+0

@VicSeedoubleyew Je ne sais pas comment voir le code interne dans JAVA, mais je sais comment le faire en C# (code interne IL) et C++ (assembleur) –

1

Le Byte Code des deux "programmes":

//first "program" 
int i = 0; 
i = i + 1; 

//second program 
int i = 0; 
i += 1; 

est le même:

0: iconst_0 
1: istore_1 
2: iinc   1, 1 
5: return 

Et quand décompiler le Byte Code ci-dessus, nous obtenons ce -

int i = 0; 
++i; 

donc peu importe celui que vous utilisez.

EDIT Ce qui précède a été testé sur jdk1.7.0_79 et Eclipse 3.8.2.