Szukaj…


Ogólne podejście

Internet zawiera mnóstwo wskazówek dotyczących poprawy wydajności programów Java. Być może najważniejszą wskazówką jest świadomość. To znaczy:

  • Zidentyfikuj możliwe problemy z wydajnością i wąskie gardła.
  • Użyj narzędzi do analizy i testowania.
  • Poznaj dobre i złe praktyki.

Pierwszy punkt należy zrobić na etapie projektowania, jeśli mówimy o nowym systemie lub module. Jeśli mówimy o starszym kodzie, na obrazie pojawiają się narzędzia do analizy i testowania. Najbardziej podstawowym narzędziem do analizy wydajności JVM jest JVisualVM, który jest zawarty w JDK.

Trzeci punkt dotyczy głównie doświadczenia i obszernych badań oraz, oczywiście, surowych wskazówek, które pojawią się na tej stronie i innych, takich jak ta .

Zmniejszenie ilości ciągów

W Javie zbyt łatwo jest utworzyć wiele instancji String, które nie są potrzebne. To i inne powody mogą spowodować, że twój program będzie miał wiele ciągów, które GC jest zajęte czyszczeniem.

Niektóre sposoby tworzenia instancji String:

myString += "foo";

Lub gorzej, w pętli lub rekurencji:

for (int i = 0; i < N; i++) {
    myString += "foo" + i;
}

Problem polega na tym, że każdy + tworzy nowy ciąg (zwykle, ponieważ nowe kompilatory optymalizują niektóre przypadki). Możliwą optymalizację można przeprowadzić za pomocą StringBuilder lub StringBuffer :

StringBuffer sb = new StringBuffer(myString);
for (int i = 0; i < N; i++) {
    sb.append("foo").append(i);
}
myString = sb.toString();

Jeśli często budujesz długie łańcuchy (na przykład SQL), użyj interfejsu API do budowania łańcuchów.

Inne rzeczy do rozważenia:

  • Ogranicz użycie replace , substring itp.
  • Unikaj String.toArray() , szczególnie w często String.toArray() kodzie.
  • Odciski dziennika, które mają być filtrowane (np. Z powodu poziomu dziennika), nie powinny być generowane (poziom dziennika powinien być wcześniej sprawdzony).
  • Użyj biblioteki jak ten w razie potrzeby.
  • StringBuilder jest lepszy, jeśli zmienna jest używana w sposób niepodzielony (między wątkami).

Oparte na dowodach podejście do dostrajania wydajności Java

Donald Knuth jest często cytowany w ten sposób:

„Programiści tracą ogromną ilość czasu na myślenie lub martwienie się o szybkość niekrytycznych części swoich programów, a te próby wydajności mają silny negatywny wpływ na debugowanie i konserwację. Powinniśmy zapomnieć o małej wydajności, powiedzmy o 97% czasu : przedwczesna optymalizacja jest źródłem wszelkiego zła. Jednak nie powinniśmy tracić naszych szans w tak krytycznych 3%. ”

źródło

Mając na uwadze tę mądrą radę, oto zalecana procedura optymalizacji programów:

  1. Przede wszystkim zaprojektuj i zakoduj swój program lub bibliotekę, kładąc nacisk na prostotę i poprawność. Na początek nie poświęcaj dużo wysiłku na wydajność.

  2. Doprowadź go do stanu roboczego i (najlepiej) opracuj testy jednostkowe dla kluczowych części bazy kodu.

  3. Opracuj test wydajności na poziomie aplikacji. Test porównawczy powinien obejmować krytyczne dla wydajności aspekty aplikacji i powinien wykonywać szereg zadań typowych dla tego, w jaki sposób aplikacja będzie używana w produkcji.

  4. Zmierz wydajność.

  5. Porównaj zmierzoną wydajność ze swoimi kryteriami, aby określić szybkość aplikacji. (Unikaj nierealistycznych, nieosiągalnych lub niewymiernych kryteriów, takich jak „tak szybko, jak to możliwe”).

  6. Jeśli spełniasz kryteria, STOP. Twoja praca jest skończona. (Wszelkie dalsze wysiłki są prawdopodobnie stratą czasu).

  7. Profiluj aplikację podczas działania testu wydajności.

  8. Sprawdź wyniki profilowania i wybierz największe (niezoptymalizowane) „hotspoty wydajności”; tj. sekcje kodu, w których aplikacja wydaje się spędzać najwięcej czasu.

  9. Przeanalizuj sekcję kodu punktu aktywnego, aby spróbować zrozumieć, dlaczego jest to wąskie gardło, i wymyśl sposób, aby przyspieszyć.

  10. Zaimplementuj to jako proponowaną zmianę kodu, przetestuj i debuguj.

  11. Uruchom ponownie test porównawczy, aby sprawdzić, czy zmiana kodu poprawiła wydajność:

    • Jeśli tak, wróć do kroku 4.
    • Jeśli nie, porzuć zmianę i wróć do kroku 9. Jeśli nie robisz postępów, wybierz inny punkt dostępu do uwagi.

W końcu dojdziesz do punktu, w którym aplikacja jest albo wystarczająco szybka, albo rozważyłeś wszystkie znaczące punkty aktywne. W tym momencie musisz przerwać to podejście. Jeśli część kodu zużywa (powiedzmy) 1% całkowitego czasu, to nawet 50% poprawa spowoduje, że aplikacja będzie ogólnie o 0,5% szybsza.

Oczywiście jest punkt, powyżej którego optymalizacja hotspotów jest stratą wysiłku. Jeśli dojdziesz do tego punktu, musisz przyjąć bardziej radykalne podejście. Na przykład:

  • Spójrz na złożoność algorytmiczną podstawowych algorytmów.
  • Jeśli aplikacja spędza dużo czasu na wyrzucaniu elementów bezużytecznych, poszukaj sposobów na zmniejszenie tempa tworzenia obiektów.
  • Jeśli kluczowe części aplikacji wymagają dużej mocy obliczeniowej i są jednowątkowe, poszukaj możliwości równoległości.
  • Jeśli aplikacja jest już wielowątkowa, poszukaj wąskich gardeł współbieżności.

Ale tam, gdzie to możliwe, polegaj na narzędziach i pomiarach, a nie na instynkcie, aby kierować optymalizacją.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow