2011-09-19 20 views
10

In x = x + 1, è x valutato due volte? In tal caso, ciò significa in x += 1, x viene valutato solo una volta? Come vengono valutate le due espressioni in termini di codice intermedio del compilatore?È x + = 1 più efficiente di x = x + 1?

Ad esempio, x++ potrebbe significare: prendere la posizione di x, caricare il contenuto di x in un registro, e incrementare il valore di x in memoria.

Inoltre ho letto che x += 1 è utile quando x non è una variabile semplice, ma un'espressione che coinvolge un array. Qualche idea del perché questo è il caso?

+11

Questo suona come un sacco di ipotesi infondate, in particolare il titolo. Non vedo una ragione per cui uno dovrebbe essere più efficiente dell'altro e sono ragionevolmente sicuro che non sia il caso della maggior parte dei compilatori C. –

+3

Un compilatore che vale i soldi che hai pagato compilerà entrambe le espressioni con lo stesso codice oggetto. Se sei preoccupato per le prestazioni: ** misura **, misura un codice diverso, diversi flag di compilazione, utilizzo di risorse diverse, tutto diverso. – pmg

+4

Sai che x + = 1 è più efficiente di x = x + 1? Hai guardato il codice dell'oggetto generato? – Joe

risposta

12

Nella maggior parte dei compilatori questi sarebbero identici

+1

E i vecchi compilatori? che non ottimizzano quanto quelli più nuovi ... perché sono valutati in modo diverso? – user7

+1

Se il compilatore è inefficiente, può ignorare il fatto che x è riferito a due volte e caricarlo, quindi eseguire l'operazione di incremento sul valore caricato. – Ofir

+0

e che dire del commento sugli array? – user7

3

quindi ci sono già alcune domande che riguardano quello che stai chiedendo qui:

x=x+1 vs. x +=1

Incrementing: x++ vs x += 1

Which is faster? ++, += or x + 1?

Il la linea di fondo è che nella maggior parte ma non tutti lingue il compilatore sta per renderle uguali in ogni caso, quindi non c'è differenza di efficienza. Le domande di cui sopra vanno in un bel po 'di dettagli sull'argomento.

0

Con gcc, è possibile ottenere il codice assembler con gcc -S foo.c. L'ho provato con x += 1 e x = x + 1 ed era lo stesso.

7

Perché x + = 1 è più efficiente di x = x + 1?

Non lo è.

Perché x ++ è più efficiente di x + = 1?

Non lo è.


La ragione per preferire x += 1 a x = x+1 avviene quando x è sostituito con un identificatore di molto più lungo, o forse un campo in una classe o struct. In questa situazione, la versione x += 1 è più leggibile e, ancora più importante, evita le insidie ​​di ripetizione.

0

Poiché prende 4 caratteri per scrivere anziché 5.

Questo è l'unico modo in cui x+=1 è "più efficiente" rispetto x=x+1. Tuttavia l'operatore += ha alcuni altri vantaggi, come il fatto che (x)+=1 funziona in macro dove x è un'espressione che potrebbe avere effetti collaterali che si desidera evitare di valutare più di una volta ...

11

Solo per darvi un "mondo reale" ad esempio, prendere in considerazione questo programma:

int main() 
{ 
    int i = 0; 
    i += 1; 
    i++; 
    i = i + 1; 
    return 0; 
} 

compilazione con GCC, a Darwin 11 con i seguenti flag:

  • -S fermata in assembler
  • -m32 alla piattaforma a 32 bit, tanto per semplificare le cose un po '

Genera il seguente programma, ad eccezione dei commenti e delle righe vuote che ho aggiunto. Dai uno sguardo specialmente ai commenti.

 .section  __TEXT,__text,regular,pure_instructions 
     .globl _main 
     .align 4, 0x90 
_main: 
     pushl %ebp    # cdecl function stuff 
     movl %esp, %ebp  # 
     subl $12, %esp   # get room for variables  
     movl $0, -12(%ebp)  # i = 0; 

     ; i += 1 
     movl -12(%ebp), %eax # load i in register a 
     addl $1, %eax   # add 1 to register a 
     movl %eax, -12(%ebp) # store it back in memory 

     ; i++ 
     movl -12(%ebp), %eax # 
     addl $1, %eax   # just the same 
     movl %eax, -12(%ebp) # 

     ; i = i + 1 
     movl -12(%ebp), %eax # 
     addl $1, %eax   # just the same 
     movl %eax, -12(%ebp) # 

     movl $0, -8(%ebp) 
     movl -8(%ebp), %eax 
     movl %eax, -4(%ebp) 
     movl -4(%ebp), %eax 
     addl $12, %esp 
     popl %ebp 
     ret 

.subsections_via_symbols 
+0

Non so perché questo non è contrassegnato come risposta, poiché fornisce prove e non solo un'opinione. – nhouser9

+0

Questo dovrebbe essere contrassegnato come la risposta. Inoltre troviamo qualche differenza negli altri compilatori o segue lo stesso schema? – SanVed

+1

@SanVed Grazie. Difficile da dire, considerando la quantità di compilatori. Ma qualsiasi compilatore con uno sviluppo decente probabilmente conterrà questa "intelligenza". I compilatori non sono solo traduttori diretti dal livello più alto al basso, c'è un'intera scienza coinvolta ed esempi come questo sono tra i più basilari e primi elementi di questa scienza. Quindi qualsiasi compilatore moderno e importante dovrebbe includerlo. – sidyll