Martwiąc się o wydajność mojej aplikacji internetowej, zastanawiam się, która z instrukcji „if / else” lub switch jest lepsza pod względem wydajności?
124
Martwiąc się o wydajność mojej aplikacji internetowej, zastanawiam się, która z instrukcji „if / else” lub switch jest lepsza pod względem wydajności?
if
itp.Odpowiedzi:
To jest mikro optymalizacja i przedwczesna optymalizacja, które są złe. Raczej martw się o czytelność i łatwość utrzymania danego kodu. Jeśli jest więcej niż dwa
if/else
sklejone ze sobą bloki lub jego rozmiar jest nieprzewidywalny, możesz bardzo rozważyćswitch
stwierdzenie.Alternatywnie możesz też pobrać Polimorfizm . Najpierw utwórz interfejs:
I zdobądź wszystkie implementacje w niektórych
Map
. Możesz to zrobić statycznie lub dynamicznie:Na koniec zamień
if/else
lubswitch
na coś takiego (pozostawiając na boku trywialne sprawdzenia, takie jak nullpointers):To może być microslower niż
if/else
alboswitch
, ale kod jest co najmniej o wiele lepsze w utrzymaniu.Jeśli mówisz o aplikacjach internetowych, możesz użyć go
HttpServletRequest#getPathInfo()
jako klawisza akcji (ostatecznie napisz trochę więcej kodu, aby podzielić ostatnią część pathinfo w pętli, aż zostanie znaleziona akcja). Znajdziesz tutaj podobne odpowiedzi:Jeśli martwisz się o ogólną wydajność aplikacji internetowej Java EE, ten artykuł może Ci się również przydać. Są inne obszary, które dają znacznie większy wzrost wydajności niż tylko (mikro) optymalizacja surowego kodu Java.
źródło
Całkowicie zgadzam się z opinią, że przedwczesna optymalizacja jest czymś, czego należy unikać.
Ale prawdą jest, że maszyna wirtualna Java ma specjalne kody bajtowe, których można użyć do przełączania ().
Zobacz specyfikację WM ( przełącznik wyszukiwania i przełącznik tabel )
Więc może wystąpić pewien wzrost wydajności, jeśli kod jest częścią wykresu wydajności procesora.
źródło
Jest bardzo mało prawdopodobne, aby przełącznik if / else lub przełącznik był źródłem problemów z wydajnością. Jeśli masz problemy z wydajnością, najpierw wykonaj analizę profilowania wydajności, aby określić, gdzie są wolne miejsca. Przedwczesna optymalizacja jest źródłem wszelkiego zła!
Niemniej jednak, można mówić o względnej wydajności przełącznika w porównaniu z if / else z optymalizacjami kompilatora Java. Po pierwsze, zauważ, że w Javie instrukcje switch działają na bardzo ograniczonej domenie - liczbach całkowitych. Zasadniczo instrukcję switch można wyświetlić w następujący sposób:
gdzie
c_0
,c_1
, ..., ic_N
są liczbami, które są integralnymi cele instrukcji switch i<condition>
musi rozwiązać, aby wyraz całkowitej.Jeśli ten zbiór jest „gęsty” - to znaczy (max (c i ) + 1 - min (c i )) / n> α, gdzie 0 <k <α <1, gdzie
k
jest większy niż pewna wartość empiryczna, a można wygenerować tablicę skoków, co jest bardzo wydajne.Jeśli ten zestaw nie jest bardzo gęsty, ale n> = β, binarne drzewo wyszukiwania może znaleźć cel w O (2 * log (n)), co również jest wydajne.
We wszystkich innych przypadkach instrukcja switch jest dokładnie tak samo wydajna, jak równoważna seria instrukcji if / else. Dokładne wartości α i β zależą od wielu czynników i są określane przez moduł optymalizacji kodu kompilatora.
Wreszcie, oczywiście, jeśli dziedziną
<condition>
nie są liczby całkowite, instrukcja switch jest całkowicie bezużyteczna.źródło
Użyj przełącznika!
Nienawidzę utrzymywać blokad if-else-block! Zrób test:
Mój standardowy kod C # do testów porównawczych
źródło
switch
es?Pamiętam, że czytałem, że w kodzie bajtowym Javy istnieją 2 rodzaje instrukcji Switch. (Myślę, że było to w 'Java Performance Tuning' Jedna z nich to bardzo szybka implementacja, która używa wartości całkowitych instrukcji switch, aby poznać przesunięcie kodu do wykonania. Wymagałoby to, aby wszystkie liczby całkowite były następujące po sobie iw dobrze zdefiniowanym zakresie , Domyślam się, że użycie wszystkich wartości Enum również należałoby do tej kategorii.
Zgadzam się jednak z wieloma innymi plakatami ... martwienie się o to może być przedwczesne, chyba że jest to bardzo gorący kod.
źródło
switch
kilka różnych sposobów, niektóre bardziej wydajne niż inne. Ogólnie rzecz biorąc, wydajność nie będzie gorsza niż prosta „if
drabinka”, ale jest wystarczająco dużo odmian (zwłaszcza w przypadku JITC), że trudno jest być o wiele bardziej precyzyjnym.Według Cliffa Click'a w jego wykładzie Java One z 2009 roku A Crash Course in Modern Hardware :
Można uzyskać pełnię slajdy tutaj .
Cliff podaje przykład (kończąc na slajdzie 30) pokazujący, że nawet jeśli procesor wykonuje zmianę nazwy rejestru, przewidywanie gałęzi i wykonanie spekulacyjne, jest w stanie rozpocząć tylko 7 operacji w 4 cyklach zegara, zanim będzie musiał zablokować się z powodu dwóch chybień w pamięci podręcznej, które wymagają 300 cykli zegara do powrotu.
Dlatego mówi, że aby przyspieszyć program, nie powinieneś zajmować się tego rodzaju drobnymi problemami, ale większymi, takimi jak to, czy wykonujesz niepotrzebne konwersje formatu danych, takie jak konwersja „SOAP → XML → DOM → SQL →… „który” przekazuje wszystkie dane przez pamięć podręczną ”.
źródło
W moim teście lepsza wydajność to ENUM> MAP> SWITCH> IF / ELSE IF w Windows7.
źródło
Time taken for String in Switch :3235 Time taken for String in if/else if :3143 Time taken for String in Map :4194 Time taken for String in ENUM :2866
W przypadku większości
switch
i większościif-then-else
bloków nie mogę sobie wyobrazić, że są jakieś zauważalne lub znaczące problemy związane z wydajnością.Ale o to chodzi: jeśli używasz
switch
bloku, samo jego użycie sugeruje, że włączasz wartość pobraną z zestawu stałych znanych w czasie kompilacji. W takim przypadku naprawdę nie powinieneś w ogóle używaćswitch
instrukcji, jeśli możesz użyćenum
metody z metodami specyficznymi dla stałej.W porównaniu z
switch
instrukcją wyliczenie zapewnia lepsze bezpieczeństwo typów i kod, który jest łatwiejszy w utrzymaniu. Wyliczenia można zaprojektować w taki sposób, aby po dodaniu stałej do zestawu stałych kod nie był kompilowany bez zapewnienia metody specyficznej dla stałej dla nowej wartości. Z drugiej strony zapomnienie o dodaniu nowegocase
doswitch
bloku może czasami zostać złapane tylko w czasie wykonywania, jeśli masz szczęście, że ustawiłeś blok tak, aby zgłosił wyjątek.Wydajność pomiędzy
switch
ienum
metodą specyficzną dla stałej nie powinna się znacząco różnić, ale ta druga jest bardziej czytelna, bezpieczniejsza i łatwiejsza w utrzymaniu.źródło