Java Language
Java Performance Tuning
Zoeken…
Algemene benadering
Het internet staat vol met tips voor prestatieverbetering van Java-programma's. Misschien is de nummer één tip bewustzijn. Dat betekent:
- Identificeer mogelijke prestatieproblemen en knelpunten.
- Gebruik analyse- en testtools.
- Ken goede praktijken en slechte praktijken.
Het eerste punt moet tijdens de ontwerpfase worden gedaan als er sprake is van een nieuw systeem of een nieuwe module. Als we het hebben over oudere code, komen analyse- en testtools in beeld. De meest basale tool voor het analyseren van uw JVM-prestaties is JVisualVM, die is opgenomen in de JDK.
Het derde punt gaat vooral over ervaring en uitgebreid onderzoek, en natuurlijk onbewerkte tips die op deze pagina en anderen, zoals deze, zullen verschijnen .
Het aantal strings verminderen
In Java is het te "gemakkelijk" om veel String-instanties te maken die niet nodig zijn. Dat en andere redenen kunnen ervoor zorgen dat uw programma veel strings heeft die de GC bezig is met opruimen.
Sommige manieren waarop u String-instanties kunt maken:
myString += "foo";
Of erger nog, in een lus of recursie:
for (int i = 0; i < N; i++) {
myString += "foo" + i;
}
Het probleem is dat elke +
een nieuwe tekenreeks maakt (meestal omdat nieuwe compilers sommige gevallen optimaliseren). Een mogelijke optimalisatie kan worden gemaakt met StringBuilder
of StringBuffer
:
StringBuffer sb = new StringBuffer(myString);
for (int i = 0; i < N; i++) {
sb.append("foo").append(i);
}
myString = sb.toString();
Als u vaak lange tekenreeksen maakt (bijvoorbeeld SQL's), gebruikt u een API voor het maken van tekenreeksen.
Andere dingen om te overwegen:
- Verminder het gebruik van
replace
,substring
etc. - Vermijd
String.toArray()
, vooral in veelgebruikte code. - Logafdrukken die bestemd zijn om te worden gefilterd (bijvoorbeeld vanwege logniveau), mogen niet worden gegenereerd (logniveau moet vooraf worden gecontroleerd).
- Gebruik bibliotheken willen deze indien nodig.
- StringBuilder is beter als de variabele op een niet-gedeelde manier (over threads) wordt gebruikt.
Een evidence-based benadering voor het afstemmen van Java-prestaties
Donald Knuth wordt vaak als volgt geciteerd:
"Programmeurs verspillen enorme hoeveelheden tijd om na te denken over of zich zorgen te maken over de snelheid van niet-kritische onderdelen van hun programma's, en deze pogingen tot efficiëntie hebben eigenlijk een sterk negatief effect wanneer debugging en onderhoud worden overwogen. We moeten kleine efficiëntie vergeten, zeg maar over 97% van de tijd : voortijdige optimalisatie is de wortel van alle kwaad. Toch moeten we onze kansen in die kritische 3% niet laten liggen. "
Met dat wijze advies in gedachten, is hier de aanbevolen procedure voor het optimaliseren van programma's:
Ontwerp en codeer eerst uw programma of bibliotheek met een focus op eenvoud en correctheid. Besteed om te beginnen niet veel aan prestaties.
Breng het in een werkende staat en ontwikkel (idealiter) eenheidstests voor de belangrijkste onderdelen van de codebase.
Ontwikkel een prestatiebenchmark op applicatieniveau. De benchmark moet betrekking hebben op de kritieke aspecten van uw toepassing en moet een reeks taken uitvoeren die typerend zijn voor de manier waarop de toepassing in productie wordt gebruikt.
Meet de prestatie.
Vergelijk de gemeten prestaties met uw criteria voor hoe snel de applicatie moet zijn. (Vermijd onrealistische, onbereikbare of niet-kwantificeerbare criteria zoals "zo snel mogelijk".)
Als u aan de criteria hebt voldaan, STOP. Je werk is gedaan. (Elke verdere inspanning is waarschijnlijk tijdverspilling.)
Maak een profiel van de toepassing terwijl deze uw prestatiebenchmark uitvoert.
Bekijk de profileringsresultaten en kies de grootste (niet-geoptimaliseerde) "prestatie-hotspots"; dat wil zeggen delen van de code waar de toepassing de meeste tijd lijkt door te brengen.
Analyseer het hotspotcodegedeelte om te proberen te begrijpen waarom het een knelpunt is en bedenk een manier om het sneller te maken.
Implementeer dat als een voorgestelde codewijziging, test en foutopsporing.
Voer de benchmark opnieuw uit om te zien of de codewijziging de prestaties heeft verbeterd:
- Zo ja, ga dan terug naar stap 4.
- Zo nee, verlaat dan de wijziging en ga terug naar stap 9. Als u geen vooruitgang boekt, kiest u een andere hotspot voor uw aandacht.
Uiteindelijk kom je op een punt waarop de applicatie snel genoeg is of je alle belangrijke hotspots hebt overwogen. Op dit punt moet u deze aanpak stoppen. Als een deel van de code (zeg) 1% van de totale tijd verbruikt, zal zelfs een verbetering van 50% de applicatie in het algemeen slechts 0,5% sneller maken.
Het is duidelijk dat er een punt is waarop optimalisatie van hotspots verspilling is. Als je op dat punt komt, moet je een radicalere aanpak volgen. Bijvoorbeeld:
- Kijk naar de algoritmische complexiteit van uw kernalgoritmen.
- Als de toepassing veel tijd besteedt aan het verzamelen van afval, zoek dan naar manieren om de snelheid waarmee objecten worden gemaakt te verminderen.
- Als belangrijke onderdelen van de applicatie CPU-intensief en single-threaded zijn, zoek dan naar mogelijkheden voor parallellisme.
- Als de toepassing al multi-threaded is, zoek dan naar gelijktijdige knelpunten.
Maar vertrouw waar mogelijk op hulpmiddelen en metingen in plaats van op instinct om uw optimalisatie-inspanningen te sturen.