Operatore ternario?: Vs se … altro

In C ++, l’operatore?: Più veloce di if () … altre istruzioni? Ci sono delle differenze tra loro nel codice compilato?

Dipende dal tuo compilatore, ma su qualsiasi compilatore moderno non c’è generalmente alcuna differenza. È qualcosa di cui non ti devi preoccupare. Concentrati sulla manutenibilità del tuo codice.

Non è più veloce C’è una differenza quando puoi inizializzare una variabile costante a seconda di alcune espressioni:

 const int x = (a 

Non puoi fare lo stesso con if-else .

Ho visto GCC trasformare l’operatore condizionale in cmov (spostamento condizionale), mentre trasformando le istruzioni in rami, il che significava nel nostro caso che il codice era più veloce quando si utilizzava l’operatore condizionale. Ma quello era un paio di anni fa, e molto probabilmente oggi, entrambi avrebbero compilato lo stesso codice.

Non c’è alcuna garanzia che verranno compilati con lo stesso codice. Se hai bisogno della performance, allora, come sempre, misura . E quando hai misurato e scoperto che 1. il tuo codice è troppo lento, e 2. è questo particolare pezzo di codice che è il colpevole, quindi studia il codice assembly generato dal compilatore e verifica tu stesso cosa sta succedendo.

Non fidatevi di regole d’oro come “il compilatore genererà sempre codice più efficiente se utilizzo l’operatore condizionale”.

Sono uguali, tuttavia, l’operatore ternario può essere utilizzato in luoghi in cui è difficile utilizzare un if / else:

 printf("Total: %d item%s", cnt, cnt != 1 ? "s" : ""); 

Facendo questa affermazione con un if / else, genererebbe un codice compilato molto diverso.


Aggiornamento dopo 8 anni …

In realtà, penso che sarebbe meglio:

 printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt); 

(In realtà, sono abbastanza sicuro che puoi sostituire “% d” nella prima stringa con “uno”)

Solo per essere un po ‘mancino …

 x ? y : x = value 

assegnerà valore a y se x non è 0 (falso).

Indipendentemente dal codice compilato, sono una cosa semanticamente diversa. ?: è un’espressione e if..else.. è una dichiarazione.

Sebbene la syntax dell’espressione condizionale sembri scomoda, è una buona cosa. Sei obbligato a fornire e le due espressioni sono controllate.

L’equivalente di if..else.. nel linguaggio funzionale basato sull’espressione come Lisp, Haskell è ? : ? : in C ++, invece di if..else.. istruzione.

Ora non posso aiutarti, potrei essere in grado di aiutarti con una domanda secondaria, voglio usarla? Se vuoi solo sapere della velocità, ignora il mio commento.

Tutto quello che posso dire è per favore essere molto intelligente su quando usare il ternario? : operatore. Può essere una benedizione tanto quanto una maledizione per la leggibilità.

Chiediti se lo trovi più facile da leggere prima di usarlo

 int x = x == 1 ? x = 1 : x = 1; if (x == 1) { x = 1 } else { x = 2 } if (x == 1) x = 1 else x = 1 

Sì Sembra stupido rendere il codice 100% fasullo. Ma quel piccolo trucco mi ha aiutato ad analizzare la mia leggibilità del codice. È la leggibilità dell’operatore che si guarda in questo esempio e non il contenuto.

SEMBRA pulito, così come il sedile del water e la maniglia della porta

Nella mia esperienza, che è limitata, ho visto pochissime persone in realtà essere in grado di estradare rapidamente le informazioni richieste da un operatore ternario, evitare se il 100% non è sicuro che sia meglio. È un dolore da aggiustare quando è infestato e penso che sia così

Mi aspetterei che sulla maggior parte dei compilatori e delle piattaforms di destinazione ci saranno casi in cui “se” è più veloce e casi in cui?: È più veloce. Ci saranno anche casi in cui una forma è più o meno compatta dell’altra. Quali casi favoriscono una forma o l’altra varieranno tra compilatori e piattaforms. Se stai scrivendo un codice critico per le prestazioni su un micro embedded, guarda cosa sta generando il compilatore in ogni caso e vedi quale è meglio. Su un PC “mainstream”, a causa dei problemi di memorizzazione nella cache, l’unico modo per vedere quale è meglio è quello di confrontare entrambe le forms in qualcosa che assomiglia alla vera applicazione.

Durante l’inversione del codice (che non ricordo, alcuni anni fa) ho visto una differenza di linea singola tra il codice macchina di:? e se-altro. Don't remember much but it is clear that implementation of both is different.

Ma ti consiglio di non scegliere uno di loro b’coz della sua efficienza, scegliere in base alla leggibilità del codice o alla tua convenienza. Felice codifica

L’operatore ternario restituisce sempre un valore. Quindi in situazioni in cui si desidera un valore di uscita dal risultato e ci sono solo 2 condizioni sempre migliori per utilizzare l’operatore ternario. Usa if-else se una delle condizioni sopra menzionate non è vera.

Penso che ci siano situazioni in cui l’inline può produrre codice “più veloce” a causa dell’ambito in cui opera. La creazione e la distruzione di oggetti può essere costosa quindi considera lo scenario seguente:

 class A{ public: A() : value(0) { cout << "Default ctor" << endl; } A(int myInt) : value(myInt) { cout << "Overloaded ctor" << endl; } A& operator=(const A& other){ cout << "= operator" << endl; value = other.value; } ~A(){ cout << "destroyed" << std::endl; } int value; }; int main() { { A a; if(true){ a = A(5); }else{ a = A(10); } } cout << "Next test" << endl; { A b = true? A(5) : A(10); } return 0; } 

Con questo codice, l'output sarà:

 Default ctor Overloaded ctor = operator destroyed destroyed Next test Overloaded ctor destroyed 

Quindi, inserendo il se, risparmiamo un sacco di operazioni necessarie per mantenere a vivo allo stesso scopo di b . Mentre è altamente probabile che la velocità di valutazione delle condizioni sia abbastanza uguale in entrambi gli scenari, il cambiamento dello scope ti costringe a prendere in considerazione altri fattori che l'inline ti consente di evitare.

Non sei obbligato a mettere tutto su una riga: –

 x = y==1 ? 2 :// else 3; 

È molto più chiaro di if / else perché puoi vedere immediatamente che entrambi i rami portano a x a cui è stato assegnato.

In CA l’operatore ternario “?:” È disponibile per build espressioni condizionali del modulo

 exp1 ? exp2:exp3 

dove exp1, exp2 e exp3 sono espressioni

per esempio

  a=20; b=25; x=(a>b)?a:b; in the above example x value will be assigned to b; 

Questo può essere scritto usando l’ istruzione if..else come segue

  if (a>b) x=a; else x=b; 

** Quindi non c’è differenza tra questi due. Questo per il programmatore di scrivere facilmente, ma per il compilatore sono entrambi uguali. *

No, vengono convertiti esattamente nello stesso codice eseguibile.