2012-03-16 5 views
104

Sono incline a "Sindrome if-condizionale" che significa che tendo ad utilizzare se le condizioni sono sempre. Uso raramente l'operatore ternario. Per esempio: L'operatore ternario è più veloce di una condizione "se"

//I like to do this: 
int a; 
if (i == 0) 
{ 
    a = 10; 
} 
else 
{ 
    a = 5; 
} 

//When I could do this: 
int a = (i == 0) ? 10:5; 

Ha importanza che uso? Quale è più veloce? Ci sono notevoli differenze di rendimento? È una pratica migliore utilizzare il codice più breve quando possibile?

Uso il linguaggio di programmazione Java.

+4

Non importa e dovresti preoccuparti del codice pulito piuttosto che delle prestazioni. In questo caso, penso che l'operatore ternario sia solo più pulito. –

+3

Inoltre, puoi farlo in questo modo: if (i == 0) a = 10; else a = 5; ' –

+11

L'ottimizzazione prematura senza profiling che mostra un'esigenza definita è cattiva, cattiva, cattiva. Usa il codice che il tuo sé futuro comprenderà meglio tra 6 mesi. –

risposta

93

Ha importanza che utilizzo?

Sì! Il secondo è molto più leggibile. Stai scambiando una linea che esprime in modo conciso ciò che vuoi contro nove linee di disordine efficace.

Quale è più veloce?

Nessuno dei due.

È consigliabile utilizzare il codice più breve quando possibile?

Non "quando possibile" ma certamente quando possibile senza effetti di detrimento. Il codice più breve è almeno potenzialmente più leggibile poiché si concentra sulla parte pertinente piuttosto che sugli effetti accidentali ("codice boilerplate").

+1

leggibile non significa che importi, perse. – Jon

+0

Anche 9 righe, se conto bene, perché c'è anche troppo spazio bianco. –

+16

@Jon: Sì, lo fa. La leggibilità è tutto ciò che conta, in modo efficace. –

8

Gli operatori ternari sono solo una scorciatoia. Si compilano nell'equivalente if-else dichiarazione, il che significa che saranno esattamente lo stesso.

30

Se c'è qualsiasi differenza di prestazioni (che dubito), sarà trascurabile. Concentrati sulla scrittura del codice più semplice e più leggibile che puoi.

Detto questo, cercare di ottenere sopra la vostra avversione dell'operatore condizionale - mentre è certamente possibile abusare di esso, può essere davvero utile in alcuni casi. Nell'esempio specifico che hai fornito, utilizzerei sicuramente l'operatore condizionale.

+0

Perché dovresti usare il condizionale qui? Vorrei usare il ternario per la pulizia. – Jon

+14

@Jon: l'operatore condizionale è il nome * effettivo * per quello che hai chiamato operatore ternario. È * un * operatore ternario, in quanto ha 3 operandi, ma il suo * nome * è l'operatore condizionale. –

+1

Ok, grazie per i chiarimenti. Stavo pensando che intendessi la sintassi esplicita di "if-else". – Jon

0

È preferibile utilizzare qualsiasi cosa si legge meglio - c'è in pratica qualsiasi differenza 0 tra le prestazioni.

In questo caso penso che l'ultima istruzione sia migliore della prima istruzione if, ma attenzione a non abusare dell'operatore ternario - a volte può davvero rendere le cose molto meno chiare.

24

Ternario Operatore esempio:

int a = (i == 0) ? 10 : 5; 

Non si può fare con l'assegnazione if/else in questo modo:

// invalid: 
int a = if (i == 0) 10; else 5; 

Questa è una buona ragione per usare l'operatore ternario.Se non si dispone di un incarico:

(i == 0) ? foo() : bar(); 

un if/else non è che molto di più il codice:

if (i == 0) foo(); else bar(); 

In casi critici di performance: misurarla. Misuralo con la macchina target, la JVM di destinazione, con dati tipici, se c'è un collo di bottiglia. Altrimenti vai per la leggibilità.

integrato nel contesto, questo breve modulo a volte è molto utile:

System.out.println ("Good morning " + (p.female ? "Miss " : "Mister ") + p.getName()); 
+0

C'è un altro motivo per usare l'operatore ternario: ti fa gestire tutti i casi. –

+0

@MikeDunlavey: Se pensi 'Oh, non dimentichiamo il secondo caso!Usiamo un operatore ternario 'puoi iniziare a scrivere' altro 'per non dimenticarlo, se il tuo cervello è così inaffidabile, per dimenticarlo nei pochi secondi in cui scrivi la tua dichiarazione. –

+0

Non si tratta solo di scrivere il "else", è ciò che si inserisce. –

15

Sì è importante, ma non a causa di codice di prestazioni di esecuzione.

La codifica più veloce (performante) è più rilevante per il looping e l'istanza dell'oggetto rispetto ai semplici costrutti di sintassi. Il compilatore dovrebbe gestire l'ottimizzazione (sarà tutto sullo stesso binario!) Quindi il tuo obiettivo dovrebbe essere l'efficienza per You-From-The-Future (gli umani sono sempre il collo di bottiglia nel software).

Josh Bloch's "Performance Anxiety" talk on Parleys.com

La risposta citando 9 linee contro uno può essere fuorviante: meno linee di codice non sempre uguale migliore. Gli operatori ternari possono essere un modo più conciso in situazioni limitate (il tuo esempio è buono).

MA possono spesso essere abusati per rendere il codice illeggibile (che è un peccato capitale) = non nidificare operatori ternari!

Considera anche futuro manutenibilità, if-else è molto più facile per estendere o modificare:

int a; 
if (i != 0 && k == 7){ 
    a = 10; 
    logger.debug("debug message here"); 
}else 
    a = 3; 
    logger.debug("other debug message here"); 
} 


int a = (i != 0 && k== 7) ? 10 : 3; // density without logging nor ability to use breakpoints 

P.S. risposta stackoverflow molto completa a To ternary or not to ternary?

+1

Non sono d'accordo con questo: è idiomatico e leggibile annidare le dichiarazioni condizionali, ad esempio, specialmente quando si testano più casi come in 'return x == 1? "uno": x == 2? "due": "molti"; '. Un corretto rientro e rottura in più linee aiuta qui. –

0

provare a utilizzare lo stato switch case. ma normalmente non è il collo di bottiglia di prefermance.

+1

In linea di massima è vero che le soluzioni che impiegano blocchi 'switch' dovrebbero essere evitate quando possono essere. Per loro natura, 'switch' si applica a un numero fisso di stati consentiti. Ciò crea una responsabilità di manutenzione del software perché "stati ammissibili" è molto comunemente un bersaglio mobile. Ad esempio, le soluzioni che utilizzano le classi 'enum' spesso funzionano meglio e più elegantemente delle soluzioni basate sui blocchi' switch'. – scottb

4

Inoltre, l'operatore ternario abilita una forma di parametro "facoltativo". Java non consente i parametri opzionali nelle firme dei metodi ma l'operatore ternario consente di allineare facilmente una scelta predefinita quando viene fornito null per un valore di parametro.

Ad esempio:

public void myMethod(int par1, String optionalPar2) { 

    String par2 = ((optionalPar2 == null) ? getDefaultString() : optionalPar2) 
      .trim() 
      .toUpperCase(getDefaultLocale()); 
} 

Nell'esempio precedente, passando null come valore del parametro String si ottiene un valore di stringa di default invece di un NullPointerException. È breve e dolce e, direi, molto leggibile. Inoltre, come è stato sottolineato, a livello di codice byte non c'è davvero alcuna differenza tra l'operatore ternario e if-then-else. Come nell'esempio precedente, la decisione su cui scegliere si basa interamente sulla leggibilità.

Inoltre, questo modello consente di rendere il parametro String veramente opzionale (se si ritiene utile farlo) sovraccaricando il metodo come segue:

public void myMethod(int par1) { 
    return myMethod(par1, null); 
} 
2

Per il nostro esempio, io preferisco il ternario o condizione operatore (?) per un motivo specifico: posso chiaramente vedere che l'assegnazione di a non è opzionale.Con un semplice esempio, non è troppo difficile da eseguire la scansione del blocco if-else di vedere che a viene assegnato a ogni clausola, ma immaginate diversi incarichi in ogni clausola:

if (i == 0) 
{ 
    a = 10; 
    b = 6; 
    c = 3; 
} 
else 
{ 
    a = 5; 
    b = 4; 
    d = 1; 
} 

a = (i == 0) ? 10 : 5; 
b = (i == 0) ? 6 : 4; 
c = (i == 0) ? 3 : 9; 
d = (i == 0) ? 12 : 1; 

Io preferisco il secondo in modo da sapere non ho perso un incarico.

Problemi correlati