it-swarm.com.de

Ist der ternäre Operator schneller als eine "if" -Bedingung in Java

Ich bin anfällig für " if-conditional syndrome ", was bedeutet, dass ich dazu neige, die ganze Zeit über Bedingungen zu verwenden. Ich verwende selten den ternären Operator. Zum Beispiel:

//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;

Ist es wichtig, was ich benutze? Welche ist schneller? Gibt es bemerkenswerte Leistungsunterschiede? Ist es besser, möglichst den kürzesten Code zu verwenden?

106
JRunner

Ist es wichtig, was ich benutze?

Ja! Der zweite ist deutlich lesbarer. Sie handeln eine Zeile, die kurz und bündig das, was Sie wollen, gegen neun Zeilen effektiver Unordnung ausdrückt.

Welche ist schneller?

Weder.

Ist es besser, möglichst den kürzesten Code zu verwenden?

Nicht "wann immer möglich", aber sicher immer wenn möglich ohne nachteilige Auswirkungen. Kürzere Codes sind zumindest potenziell lesbarer, da sie sich auf den relevanten Teil konzentrieren und nicht auf Nebeneffekte („Boilerplate-Code“).

96
Konrad Rudolph

Wenn es irgendwelche Leistungsunterschiede gibt (was ich bezweifle), wird es vernachlässigbar sein. Konzentrieren Sie sich auf das Schreiben des einfachsten und lesbarsten Codes.

Versuchen Sie dennoch, Ihre Abneigung gegen den bedingten Operator zu überwinden - obwohl es durchaus möglich ist, ihn übermäßig zu nutzen, kann es in manchen Fällen wirklich nützlich sein. In dem von Ihnen angegebenen Beispiel würde ich definitiv den Bedingungsoperator verwenden.

31
Jon Skeet

Beispiel eines ternären Betreibers:

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

Sie können keine Zuordnung mit if/else machen: 

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

Dies ist ein guter Grund, den ternären Operator zu verwenden. Wenn Sie keinen Auftrag haben:

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

ein if/else ist nicht so viel mehr Code: 

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

In leistungskritischen Fällen: Messen Sie es. Messen Sie es mit der Zielmaschine, der Ziel-JVM, mit typischen Daten, wenn ein Engpass vorliegt. Ansonsten geht es um die Lesbarkeit.

Eingebettet in den Kontext ist die Kurzform manchmal sehr praktisch:

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

Ja, das ist wichtig, aber nicht wegen der Leistung bei der Codeausführung.

Eine schnellere (performante) Codierung ist für das Looping und die Objektinstanziierung relevanter als einfache Syntaxkonstrukte. Der Compiler sollte mit der Optimierung fertig werden (es wird sich alles um die gleiche Binärdatei handeln!). Ihr Ziel sollte also die Effizienz für You-From-The-Future sein (Menschen sind immer der Engpass in Software).

Josh Blochs "Performance-Angst" -Diskussion auf Parleys.com

Die Antwort, die 9 Zeilen im Vergleich zu einer Zeile zitiert, kann irreführend sein: Weniger Codezeilen sind nicht immer gleichwertiger. Ternäre Operatoren können in begrenzten Situationen eine prägnantere Methode sein (Ihr Beispiel ist ein gutes Beispiel).

ABER sie können oft missbraucht werden, um Code unlesbar zu machen (was eine Hauptsünde ist) = ternäre Operatoren nicht verschachteln!

Berücksichtigen Sie auch die zukünftige Wartbarkeit. Wenn-else viel einfacher zu erweitern oder zu ändern ist:

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. sehr vollständige stackoverflow-Antwort an zu ternär oder nicht zu ternär?

15
foupfeiffer

Ternäre Operatoren sind nur eine Abkürzung. Sie werden in die entsprechende if-else-Anweisung kompiliert, was bedeutet, dass sie genau - gleich sind.

8
Jon Egeland

Der ternäre Operator ermöglicht auch die Form eines optionalen Parameters. Java erlaubt keine optionalen Parameter in Methodensignaturen. Mit dem ternären Operator können Sie problemlos eine Standardauswahl vornehmen, wenn für einen Parameterwert null angegeben wird.

Zum Beispiel:

public void myMethod(int par1, String optionalPar2) {

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

Wenn Sie im obigen Beispiel null als String-Parameterwert übergeben, erhalten Sie einen Standard-String-Wert anstelle einer NullPointerException. Es ist kurz und süß und ich würde sagen, sehr lesbar. Darüber hinaus gibt es, wie bereits gesagt wurde, auf Byte-Ebene keinen Unterschied zwischen dem ternären Operator und dem Wenn-Dann-Anderen. Wie im obigen Beispiel basiert die Entscheidung, zu entscheiden, vollständig auf der Lesbarkeit.

Darüber hinaus können Sie mit diesem Muster den Parameter String wirklich optional machen (wenn dies als nützlich erachtet wird), indem Sie die Methode wie folgt überladen:

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

Für das gegebene Beispiel bevorzuge ich den ternären oder Bedingungsoperator (?) aus einem bestimmten Grund: Ich kann deutlich erkennen, dass die Zuweisung von a nicht optional ist. Mit einem einfachen Beispiel ist es nicht zu schwierig, den if-else-Block zu scannen, um festzustellen, dass a in jeder Klausel zugewiesen ist. Stellen Sie sich jedoch mehrere Zuweisungen in jeder Klausel vor:

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;

Ich ziehe letzteren vor, damit Sie wissen, dass Sie keine Aufgabe verpasst haben.

1
Matthew Carlson

Verwenden Sie am besten das, was Sie besser lesen - es gibt praktisch nur einen Unterschied zwischen der Leistung.

Ich denke, in diesem Fall liest sich die letzte Aussage besser als die erste if-Anweisung, aber achtet darauf, den ternären Operator nicht zu stark zu beanspruchen - manchmal kann dies die Dinge viel weniger klar machen.

0
Michael Berry

Versuchen Sie, die switch case-Anweisung zu verwenden, aber normalerweise ist dies nicht der Leistungsengpass.

0
Zava