Istnieją dwa rodzaje if
oświadczeń w Javie - Classic: if {} else {}
i skrócone: exp ? value1 : value2
. Czy jeden jest szybszy od drugiego, czy są takie same?
komunikat:
int x;
if (expression) {
x = 1;
} else {
x = 2;
}
operator trójskładnikowy:
int x = (expression) ? 1 : 2;
if
jest do użytku w wyciągach.?
jest używany w wyrażeniach.Odpowiedzi:
Jest tam tylko jeden rodzaj instrukcji „jeśli”. Drugi to wyrażenie warunkowe. Co do tego, który będzie działał lepiej: mogą skompilować się do tego samego kodu bajtowego i spodziewałbym się, że będą się zachowywać identycznie - lub tak blisko, że zdecydowanie nie będziesz chciał wybierać jednego z nich pod względem wydajności.
Czasami
if
instrukcja będzie bardziej czytelna, czasami operator warunkowy będzie bardziej czytelny. W szczególności zalecałbym użycie operatora warunkowego, gdy dwa operandy są proste i wolne od skutków ubocznych, podczas gdy jeśli głównym celem tych dwóch gałęzi są ich skutki uboczne, prawdopodobnie użyłbymif
instrukcji.Oto przykładowy program i kod bajtowy:
public class Test { public static void main(String[] args) { int x; if (args.length > 0) { x = 1; } else { x = 2; } } public static void main2(String[] args) { int x = (args.length > 0) ? 1 : 2; } }
Dekompilacja kodu bajtowego za pomocą
javap -c Test
:public class Test extends java.lang.Object { public Test(); Code: 0: aload_0 1: invokespecial #1 4: return public static void main(java.lang.String[] Code: 0: aload_0 1: arraylength 2: ifle 10 5: iconst_1 6: istore_1 7: goto 12 10: iconst_2 11: istore_1 12: return public static void main2(java.lang.String[ Code: 0: aload_0 1: arraylength 2: ifle 9 5: iconst_1 6: goto 10 9: iconst_2 10: istore_1 11: return }
Jak widać, jest tu niewielka różnica w
istore_1
kodzie bajtowym - czy występuje w brance, czy nie (w przeciwieństwie do mojej poprzedniej bardzo błędnej próby :) ale byłbym bardzo zaskoczony, gdyby JITter skończył z innym rodzimym kodem.źródło
main
imain2
być dokładnie tym samym?Oba twoje przykłady prawdopodobnie skompilują się do identycznego lub prawie identycznego kodu bajtowego, więc nie powinno być różnicy w wydajności.
Gdyby była różnica w szybkości wykonywania, nadal powinieneś używać najbardziej idiomatycznej wersji (która byłaby drugą do przypisywania pojedynczej zmiennej na podstawie prostego warunku i dwóch prostych wyrażeń podrzędnych, a pierwszą do wykonywania bardziej złożonych operacji lub operacje, które nie mieszczą się w jednej linii).
źródło
Te są takie same. Oba są dość szybkie, zwykle około 10-30 nanosekund. (w zależności od sposobu użytkowania) Czy ten przedział czasowy jest dla Ciebie ważny?
Powinieneś robić to, co uważasz za najbardziej oczywiste.
źródło
Wystarczy dodać do wszystkich pozostałych odpowiedzi:
Drugie wyrażenie jest często nazywane trzeciorzędnym / potrójnym operatorem / instrukcją. Może być bardzo przydatne, ponieważ zwraca wyrażenie. Czasami sprawia, że kod jest bardziej przejrzysty w przypadku typowych krótkich instrukcji.
źródło
final
pola, możesz użyć bloków konstruktora, aby ustawić wartość (chociaż operator warunkowy wygląda miliard razy lepiej w IMO), a ze zmiennymi lokalnymi możesz przypisać wartość przed pierwszym użyciem później w bloku kodu, Jestem w środku . Myślę, że jedyny przypadek, w którym trójskładnik dałby przewagę,if-else
to wywołaniesuper(...)
lubthis(...)
wewnątrz konstruktora.ani - będą kompilowane do tego samego.
źródło
Operator trójargumentowy jest szybszy niż warunek if-else.
public class TerinaryTest { public static void main(String[] args) { int j = 2,i = 0; Date d1 = new Date(); for(long l=1;l<100000000;l++) if(i==1) j=1; else j=0; Date d2 = new Date(); for(long l=1;l<100000000;l++) j=i==1?1:0; Date d3 = new Date(); System.out.println("Time for if-else: " + (d2.getTime()-d1.getTime())); System.out.println("Time for ternary: " + (d3.getTime()-d2.getTime())); } }
Wyniki testu:
Trail-1:
Czas na if-else: 63
Czas na trójkę: 31
Trail-2:
Czas na coś innego: 78
Czas na trójkę: 47
Trail-3:
Czas na if-else: 94
Czas na trójkę: 31
Trail-4:
Czas na coś innego: 78
Czas na trójkę: 47
źródło