2011-11-04 14 views
6

Obecnie używam instrukcji switch do obsługi typów wiadomości przychodzących, których jest około 20 różnych przypadków. Niektóre z tych przypadków są o rząd wielkości bardziej prawdopodobne niż inne.Optymalizacja instrukcji przełączania Java w wielu przypadkach?

Czy kompilator hotspot w stanie zoptymalizować kolejność rozpatrywania spraw, aby znaleźć właściwą sprawę do wykonania lub powinna wyglądać struktura kodu tak, że najczęstsze przypadki pojawiają się pierwsze:

switch(messageType) 
{ 
    case MOST_COMMON: 
     // handle it 
     break; 

... 
    case LEAST_COMMON: 
     // handle it 
     break; 
} 

Wszystkie przypadki są wzajemnie się wykluczają .

Czy mogę lepiej wykorzystać wzorzec strategii i wyszukiwanie mapy dla typu wiadomości?

Wydajność jest kluczową kwestią, ponieważ obsługuję tysiące wiadomości na sekundę i próbuję zmniejszyć nakłady związane z tworzeniem obiektów i wywołaniem metody.

Dziękujemy,

Chris

Edit: Dzięki za wskazówki. messageType jest int z wąskim zakresem wartości, więc wygląda na to, że skompiluje kod bajtowy "tableswitch", więc nie trzeba zmieniać kolejności przypadków.

odpowiedniej części specyfikacji JVM jest tutaj http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14942

+1

Większość kompilatorów IIRC obsługuje instrukcje 'switch' w C i C++ z tablicami odnośników. Java może zrobić to samo. Ale mogę się mylić. – NullUserException

+0

możliwy duplikat [Java: If vs. Switch] (http://stackoverflow.com/questions/1061101/java-if-vs-switch) –

+0

JIT * powinien * optymalizować ścieżkę podczas wykonywania. Zaryzykowałbym oba mechanizmy, aby zobaczyć na pewno. –

Odpowiedz

3

Jeśli nie jesteś pewien, że to stwierdzenie jest przełącznik powodując problemy z wydajnością, to sugeruję, że jesteś optymalizacji przedwcześnie. Sprawdź także the accepted answer to this question.

+0

Cześć Mike, punkt wzięty :) Ten kod dotyczy kilkaset milionów zdarzeń na dzień roboczy i odpowiada za około 30% cykli procesora w programie. Chciałem tylko opinii na temat JIT, zanim zagłębię się w specyfikację JVM. – ChrisWhoCodes

3

Jeśli wartości te są wartościami enum lub są gęsto rozdzielone, to wartościowe uporządkowanie nie pomoże, gdy kompilator JIT uruchomi go, aby przekształcić go w tabelę odnośników.

Jeśli korzystasz z przełączników łańcuchów Java7 lub wartości rozproszonych, to najpopularniejsze powinny być pierwsze, ponieważ zmieniają się w kaskadowy zestaw operacji testowych i rozgałęzień na poziomie if.

+0

z przełącznikami łańcuchowymi java7 będzie wolniej, ponieważ jednak zamienia się w kaskadowe instrukcje "if", które będą używać "równa się" przy dopasowywaniu ciągów znaków – maks

+0

Cześć Mike, przełącznik jest na int z wąskim zakresem wartości, więc myślę, że odpowiedź jest tabela odnośników i nie trzeba zmieniać kolejności klauzul. – ChrisWhoCodes

+0

@maks, myślę, że się zgadzam. Czy próbujesz wskazać mi część mojej odpowiedzi, która jest zła lub po prostu uwagi na temat przełączników łańcuchowych w ogóle? –

1

Instrukcja switch jest sprawdzianem określającym, do którego bloku kodu należy przejść. Nie jest to seria sprawdzeń if/else, a kolejność deklarowania bloków nie ma wpływu na wydajność. tj. wszystkie wartości obserwacji są sprawdzane jednakowo i jednocześnie.

Kod pseudo to samo co (o wąskim zakresie wartości int)

goto case_label[messageType.ordinal()]; 

Dla dużej wartości int zakresie inną strukturę tablicy jest używany. (Zakładam, że jest to tablica asocjacyjna)

Procesor może wykorzystywać przewidywanie rozgałęzień, a jeśli jeden przypadek jest znacznie bardziej powszechny niż inne, może dynamicznie optymalizować wykonywanie.

Powiązane problemy