2014-07-25 27 views
7

Wykonywanie testu wydajności usług REST Java Widzę nieoczekiwany wzorzec: metoda, która tworzy i zwraca zawsze ten sam obiekt o wartości w każdym wywołaniu działa szybciej niż inna wersja, która właśnie zwraca obiekt wartości przechowywany w polu klasy lub obiektu.Co optymalizacja JVM powoduje te wyniki wydajności?

Kod:

@POST @Path("inline") public Response inline(String s) { 
    return Response.status(Status.CREATED).build(); 
}  

private static final Response RESP = Response.status(Status.CREATED).build(); 
@POST @Path("staticfield") public Response static(String s) { 
    return RESP; 
} 

private final Response resp = Response.status(Status.CREATED).build(); 
@POST @Path("field") public Response field(String s) { 
    return resp; 
} 

kod binarny:

  • inline (szybsze) getstatic, invokestatic, invokevirtual, areturn
  • statyczne złożony (wolniej) getstatic, areturn
  • Pole obiektu (wolniej): aload, getfield, areturn

Wydajność (stosując Apache AB, pojedyncze nici, kilka serii ze zgodnych wyników):

  • wbudowanych: 17078.29 [#/s] (średnia)
  • statyczne pole: 5242,64 [#/s] (średnia)
  • Przedmiot doświadczenia: 5417,40 [#/s] (średnia)

Środowisko: RHEL6 + JDK Oracle 1.7.0_60-b19 64bits

Czy możliwe jest, że JVM zoptymalizowała wersję wbudowaną z natywnym kodem, ale nigdy nie rozważała optymalizacji pozostałych dwóch, ponieważ są one już dość małe?

+0

Myślę, że najprawdopodobniej coś nie działa tak, jak myślisz, poza powyższym kodem. –

+0

"Zwraca zawsze ten sam obiekt wartości" ... Być może warstwa REST wie, że wynik może być wtedy buforowany? –

+1

Prześlij kompletny, możliwy do porównania test porównawczy. Tylko wtedy możemy zagłębić się w to, co się dzieje. – tmyklebu

Odpowiedz

3

Jak podkreślono w komentarzach, trudno powiedzieć, nie patrząc na zgromadzenie. Ponieważ używamy REST-a, zakładam jednak, że trudno będzie powiedzieć od zespołu, ponieważ jest dość dużo kodu do przeczytania.

Zamiast tego chcę dać ci wykształcone domysły, ponieważ twój kod jest archetypowym przykładem zastosowania costant folding. Gdy wartość jest inline i nie jest odczytywana z pola, JVM może bezpiecznie założyć, że ta wartość jest stała. Kiedy JIT kompiluje metodę, stała ekspresja może więc być bezpiecznie połączona z twoim kodem szkieletowym, co prawdopodobnie prowadzi do mniejszej JIT i poprawy wydajności. W przypadku wartości pola, nawet wartości final, nie można przyjąć wartości stałej, ponieważ wartość pola może się zmienić. (Dopóki wartość pola nie jest stałą czasową kompilacji , prymitywną lub stałą String, które są zaznaczone przez javac.) JVM może zatem prawdopodobnie nie stale fałdować wartości.

Można read more on constant folding w tutorialu do JMH jeżeli zostanie stwierdzone:

Jeśli JVM zdaje sobie sprawę, wynik obliczeń jest taki sam bez względu na to, że można sprytnie optymalizacji. W naszym przypadku oznacza to, że możemy przenieść obliczenia poza wewnętrzną pętlę JMH. Można temu zapobiec, odczytując zawsze dane wejściowe ze stanu, obliczając wynik na podstawie tego stanu, a następnie przestrzegając reguł, aby zapobiec DCE.

Mam nadzieję, że skorzystałeś z takich ram. W przeciwnym razie dane o skuteczności nie będą poprawne.

Odczytywania kodu bajtowego, nie można na ogół dowiedzieć się wiele o wydajności środowiska wykonawczego, ponieważ kompilator JIT może dostroić kod bajtowy do dowolnego elementu podczas optymalizacji. Układ kodu bajtowego powinien mieć znaczenie tylko wtedy, gdy kod jest interpretowany, co zwykle nie jest stanem, w którym można zmierzyć wydajność, ponieważ krytyczny pod względem wydajności kod jest zawsze kompilowany JIT.

+0

To jest najlepsza odpowiedź do tej pory. Powtórzyłem testy wydajności bez żadnych frameworków, a metoda inline jest wolniejsza (wyniki przeciwne). Tak więc, niezależnie od optymalizacji, dzieje się to tylko wtedy, gdy aktywny jest kod strukturalny. Jak sam mówisz, trudno mieć pewność, że tak właśnie się dzieje w tym przypadku, ale twoje wyjaśnienie dobrze pasuje do kontekstu i nauczyłem się czegoś nowego dzięki twojej odpowiedzi. Dzięki! – Sebastian

Powiązane problemy