SlideShare une entreprise Scribd logo
1  sur  25
Zaawansowane aspekty
programowania w javie
Benchmarking
Benchmarking
• Po co nam Benchmarki
• Typowe problemy w mierzeniu wydajności kodu
• Narzędzia pozwalające na porównywanie wydajności
Po co nam Benchmarki
• Porównywanie wydajności alternatywnych rozwiązań
• Sprawdzanie wydajności bez konieczności budowy
całego rozwiązania
• Eksperymentowanie z nowymi rozwiązaniami
Rodzaje benchmarków
• Makro Benchmarki
• Porównywanie dużych funkcjonalności
• Całe procesy
• Całe systemy
• Cała JVM
• Mikro Benchmarki
• Niewielki kawałki kodu
• Krótki czas wykonania
Co w tym trudnego?
long start = System.currentTimeMillis();
work();
System.out.println(
System.currentTimeMillis() - start);
Co może pójść nie tak?
• Pomiar czasu
• Optymalizacje kompilatora
• Warm up
• Różnice platform
Pomiar czasu
• Ziarnistość pomiaru czasu
(~30 ns Linux, ~300 ns Windows [1t])
• Ukryty narzut System.nanoTime();
• Błąd pomiaru
• różnice w implementacji timerów w systemach
operacyjnych
Optymalizacje kompilatora -
pętle
• Rozwijanie pętli
• Piplineing
long start = System.nanoTime();
for (int i = 0; i < 100000; i++) {
work();
}
System.out.println((System.nanoTime() - start)/100000);
Optymalizacje kompilatora –
Constant Folding
public int measuredMethod(){
// start measurement
return 42 + work();
// end of measurement
}
Optymalizacje kompilatora –
False Sharing
int someCounter;
int completelyDifferentCounter;
// on Thread 1
public int measuredMethod1(){
return work(someCounter);
}
// on Thread 2
public int measuredMethod2(){
return work(completelyDifferentCounter);
}
Warm up
• -XX:CompileThreshold=[1500,2000,10000]
• -XX:-PrintCompilation
• -XX:MaxInlineSize=35
• -XX:+PrintInlining
• -XX:LoopUnrollLimit=n
Różnice systemów operacyjnych
• Różnice w implementacji JVM
• Różnice timerów
• Różnice scheduler’ów
• 32 vs 64 bit
• Niektóre optymalizacje dostępne są dla wybranych
OS’ów
• Niektóre bug’i też ;)
Narzędzia
• System.nanoTime()
• Caliper
• JMH
Czym jest JMH i jak może
pomóc
• Narzędzie do budowania benchmarków
• Pomaga w uniknięciu typowych problemów
• Nie zwalnia z myślenia o nich.
• Java -> org.openjdk.jmh:jmh-java-benchmark-archetype
• Scala -> org.openjdk.jmh:jmh-scala-benchmark-archetype
-> sbt-jmh plugin
• Groovy -> org.openjdk.jmh:jmh-groovy-benchmark-
archetype
• Kotlin -> org.openjdk.jmh:jmh-java-benchmark-archetype
Nowy benchmark
package pl.itkontekst.jmhtest;
import org.openjdk.jmh.annotations.Benchmark;
public class MyBenchmark {
@Benchmark
public void testMethod(){
}
}
# JMH 1.14.1 (released 13 days ago)
# VM version: JDK 1.8.0_77, VM 25.77-b03
# VM invoker: C:Program FilesJavajre1.8.0_77binjava.exe
# VM options: <none>
# Warmup: 20 iterations, 1 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: pl.itkontekst.jmhtest.MyBenchmark.testMethod
# Run progress: 0,00% complete, ETA 00:06:40
# Fork: 1 of 10
# Warmup Iteration 1: 3321638210,400 ops/s
# Warmup Iteration 2: 3035709856,963 ops/s
…
Iteration 19: 3292590873,371 ops/s
Iteration 20: 3352591339,138 ops/s
Result "testMethod":
3336940878,008 ?(99.9%) 21593035,964 ops/s [Average]
(min, avg, max) = (2837336846,716, 3336940878,008, 3433712311,191), stdev =
91426266,353
CI (99.9%): [3315347842,045, 3358533913,972] (assumes normal distribution)
# Run complete. Total time: 00:06:43
Benchmark Mode Cnt Score Error Units
MyBenchmark.testMethod thrpt 200 3336940878,008 ? 21593035,964 ops/s
Opcje pomiarów
@Fork(1)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {
@Benchmark
public void testMethod() {
}
}
Klasy Stanu, setup, parametry,
Black Hole
@State(Scope.Benchmark)
public static class MyState {
@Param({"1","2","3"})
int value;
@Setup
public void init(){}
}
@Benchmark
public void testAdd(Blackhole blackhole,MyState state) {
blackhole.consume(state.value+state.value);
Blackhole.consumeCPU(10);
}
@Benchmark
public void testMethod(Blackhole blackhole) {
Blackhole.consumeCPU(10);
}
Wątki, Grupy, Padding
@Threads(4)
public class MyBenchmark {
@State(Scope.Benchmark)
public static class MyState {
@Param({"2"})
int value;
}
@State(Scope.Benchmark)
public static class MyState2 {
@Param({"1"})
int value2;
}
@Benchmark
@Group("add")
public void testAdd(Blackhole blackhole,MyState state) {
blackhole.consume(state.value+state.value);
}
@Benchmark
@Group("add")
public void testAdd2(Blackhole blackhole,MyState2 state) {
blackhole.consume(state.value2+state.value2);
}
}
Kontrola pracy kompilatora
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
public void testDontInline(){}
@CompilerControl(CompilerControl.Mode.INLINE)
public void testForceInline(){}
@CompilerControl(CompilerControl.Mode.EXCLUDE)
public void testDontCompile(){}
Programowa kontrola
uruchamiania
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(MyBenchmark.class.getSimpleName())
.warmupIterations(1)
.measurementIterations(3)
.forks(1)
.build();
new Runner(opt).run();
}
Profilery
java -jar benchmarks.jar -lprof
Supported profilers:
cl: Classloader profiling via standard MBeans
comp: JIT compiler profiling via standard MBeans
gc: GC profiling via standard MBeans
hs_cl: HotSpot (tm) classloader profiling via implementation-specific MBeans
hs_comp: HotSpot (tm) JIT compiler profiling via implementation-specific MBeans
hs_gc: HotSpot (tm) memory manager (GC) profiling via implementation-specific
MBeans
hs_rt: HotSpot (tm) runtime profiling via implementation-specific MBeans
hs_thr: HotSpot (tm) threading subsystem via implementation-specific MBeans
pauses: Pauses profiler
perf: Linux perf Statistics
perfasm: Linux perf + PrintAssembly Profiler
perfnorm: Linux perf statistics, normalized by operation count
stack: Simple and naive Java stack profiler
Unsupported profilers:
xperfasm: <none>
Stack profiler
Stack profiler:
....[Thread state distributions]....................................................................
97,2% RUNNABLE
2,8% WAITING
....[Thread state: RUNNABLE]........................................................................
56,8% 58,5% pl.itkontekst.jmhtest.MyBenchmark.testAdd
39,8% 41,0%
pl.itkontekst.jmhtest.generated.MyBenchmark_add_jmhTest.testAdd_thrpt_jmhStub
0,3% 0,3% sun.misc.Unsafe.compareAndSwapInt
0,1% 0,1% java.lang.Thread.currentThread
0,1% 0,1% sun.misc.Unsafe.unpark
....[Thread state: WAITING].........................................................................
2,8% 100,0% sun.misc.Unsafe.park
Wyniki
java -jar benchmarks.jar -lrf
Available formats: text, csv, scsv, json, latex
java -jar benchmarks.jar -rff output.csv
Podsumowanie
• Pisanie Mikro Benchmarków nie jest trywialne
• JMH pomaga w unikaniu typowych problemów ale nie
zwalnia z myślenia o nich
• JMH nie zastąpi ostatecznych testów wydajnościowych
• JIT to potężny oręż, który może Ci obciąć rękę kiedy nie
będziesz uważny

Contenu connexe

Tendances

Narzędzie zarządzania testowaniem. Badanie TestRail.
Narzędzie zarządzania testowaniem. Badanie TestRail.Narzędzie zarządzania testowaniem. Badanie TestRail.
Narzędzie zarządzania testowaniem. Badanie TestRail.Radoslaw Smilgin
 
Narzedzia zarządzania testowaniem. Badanie - SynapseRT
Narzedzia zarządzania testowaniem. Badanie - SynapseRTNarzedzia zarządzania testowaniem. Badanie - SynapseRT
Narzedzia zarządzania testowaniem. Badanie - SynapseRTRadoslaw Smilgin
 
Automation of functional tests using JMeter Part II (in Polish)
Automation of functional tests using JMeter Part II (in Polish)Automation of functional tests using JMeter Part II (in Polish)
Automation of functional tests using JMeter Part II (in Polish)Tieto Corporation
 
Narzedzia zarządzania testowaniem. Badanie SpiraTest
Narzedzia zarządzania testowaniem. Badanie SpiraTestNarzedzia zarządzania testowaniem. Badanie SpiraTest
Narzedzia zarządzania testowaniem. Badanie SpiraTestRadoslaw Smilgin
 
Narzędzia zarzadzania testowaniem - analiza rynku
Narzędzia zarzadzania testowaniem - analiza rynkuNarzędzia zarzadzania testowaniem - analiza rynku
Narzędzia zarzadzania testowaniem - analiza rynkuRadoslaw Smilgin
 
Narzedzia zarządzania testowaniem.Wyniki.
Narzedzia zarządzania testowaniem.Wyniki.Narzedzia zarządzania testowaniem.Wyniki.
Narzedzia zarządzania testowaniem.Wyniki.Radoslaw Smilgin
 
Testy integracyjne
Testy integracyjneTesty integracyjne
Testy integracyjnePROSKAR
 
Adam Roman - Automatyczne projektowanie testów
Adam Roman - Automatyczne projektowanie testówAdam Roman - Automatyczne projektowanie testów
Adam Roman - Automatyczne projektowanie testówkraqa
 
KraQA VIII - Techniki projektowania testów
KraQA VIII - Techniki projektowania testów KraQA VIII - Techniki projektowania testów
KraQA VIII - Techniki projektowania testów kraqa
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Cloudskraqa
 

Tendances (11)

Narzędzie zarządzania testowaniem. Badanie TestRail.
Narzędzie zarządzania testowaniem. Badanie TestRail.Narzędzie zarządzania testowaniem. Badanie TestRail.
Narzędzie zarządzania testowaniem. Badanie TestRail.
 
Narzedzia zarządzania testowaniem. Badanie - SynapseRT
Narzedzia zarządzania testowaniem. Badanie - SynapseRTNarzedzia zarządzania testowaniem. Badanie - SynapseRT
Narzedzia zarządzania testowaniem. Badanie - SynapseRT
 
Automation of functional tests using JMeter Part II (in Polish)
Automation of functional tests using JMeter Part II (in Polish)Automation of functional tests using JMeter Part II (in Polish)
Automation of functional tests using JMeter Part II (in Polish)
 
Narzedzia zarządzania testowaniem. Badanie SpiraTest
Narzedzia zarządzania testowaniem. Badanie SpiraTestNarzedzia zarządzania testowaniem. Badanie SpiraTest
Narzedzia zarządzania testowaniem. Badanie SpiraTest
 
Dodatkowe narzędzia do testów wydajnościowych
Dodatkowe narzędzia do testów wydajnościowychDodatkowe narzędzia do testów wydajnościowych
Dodatkowe narzędzia do testów wydajnościowych
 
Narzędzia zarzadzania testowaniem - analiza rynku
Narzędzia zarzadzania testowaniem - analiza rynkuNarzędzia zarzadzania testowaniem - analiza rynku
Narzędzia zarzadzania testowaniem - analiza rynku
 
Narzedzia zarządzania testowaniem.Wyniki.
Narzedzia zarządzania testowaniem.Wyniki.Narzedzia zarządzania testowaniem.Wyniki.
Narzedzia zarządzania testowaniem.Wyniki.
 
Testy integracyjne
Testy integracyjneTesty integracyjne
Testy integracyjne
 
Adam Roman - Automatyczne projektowanie testów
Adam Roman - Automatyczne projektowanie testówAdam Roman - Automatyczne projektowanie testów
Adam Roman - Automatyczne projektowanie testów
 
KraQA VIII - Techniki projektowania testów
KraQA VIII - Techniki projektowania testów KraQA VIII - Techniki projektowania testów
KraQA VIII - Techniki projektowania testów
 
Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
 

Similaire à Benchmarking

4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł GrajewskiPROIDEA
 
Poznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven DevelopmentPoznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven Developmentbartlomiej.szafko
 
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVMKopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVMArtur Skowroński
 
Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?javOnet
 
Podstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptxPodstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptxKatarzyna Javaheri-Szpak
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?The Software House
 
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegroallegro.tech
 
Perl. Testowanie. Zapiski programisty
Perl. Testowanie. Zapiski programistyPerl. Testowanie. Zapiski programisty
Perl. Testowanie. Zapiski programistyWydawnictwo Helion
 
WJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof Ślusarski
WJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof ŚlusarskiWJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof Ślusarski
WJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof ŚlusarskiKrzysztof Ślusarski
 
SCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa IT
SCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa ITSCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa IT
SCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa ITRedge Technologies
 
Jak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricksJak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricksXSolve
 
Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...
Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...
Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...Mateusz Paprocki, PMP
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlSebastian Marek
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyqbeuek
 
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...Future Processing
 
Angular 4 pragmatycznie
Angular 4 pragmatycznieAngular 4 pragmatycznie
Angular 4 pragmatycznieSages
 
Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6The Software House
 

Similaire à Benchmarking (20)

4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
 
Poznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven DevelopmentPoznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven Development
 
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVMKopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
Kopiąc Trufle - Odkrywanie tajemnic najmniej zrozumiałego elementu GraalVM
 
Wprowadzenie do PHPUnit
Wprowadzenie do PHPUnitWprowadzenie do PHPUnit
Wprowadzenie do PHPUnit
 
Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?Jak podwoić wartość kodu .NET?
Jak podwoić wartość kodu .NET?
 
Podstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptxPodstawy testowania oprogramowania INCO 2023.pptx
Podstawy testowania oprogramowania INCO 2023.pptx
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
 
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
 
[TestWarez 2017] Zen testów wydajnościowych
[TestWarez 2017] Zen testów wydajnościowych[TestWarez 2017] Zen testów wydajnościowych
[TestWarez 2017] Zen testów wydajnościowych
 
Perl. Testowanie. Zapiski programisty
Perl. Testowanie. Zapiski programistyPerl. Testowanie. Zapiski programisty
Perl. Testowanie. Zapiski programisty
 
WJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof Ślusarski
WJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof ŚlusarskiWJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof Ślusarski
WJUG #257 Just-In-Time compiler - ukryty "przyjaciel" - Krzysztof Ślusarski
 
SCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa IT
SCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa ITSCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa IT
SCAP – standaryzacja formatów wymiany danych w zakresie bezpieczeństwa IT
 
Jak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricksJak migrować kod legacy do Symfony? Tips & tricks
Jak migrować kod legacy do Symfony? Tips & tricks
 
university day 1
university day 1university day 1
university day 1
 
Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...
Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...
Jak oszczędzać czas zespołu w środowisku mikroserwisów, czyli efektywny flow ...
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPl
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatyczny
 
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
[Quality Meetup #9] TestOps, QAOps - czy ktoś taki istnieje? - Aleksandra Kor...
 
Angular 4 pragmatycznie
Angular 4 pragmatycznieAngular 4 pragmatycznie
Angular 4 pragmatycznie
 
Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6Wprowadzenie do testów wydajnościowych w k6
Wprowadzenie do testów wydajnościowych w k6
 

Plus de Wojciech Oczkowski (7)

bitconf 2019 - Intro
bitconf 2019 - Introbitconf 2019 - Intro
bitconf 2019 - Intro
 
bitconf2019 - Close
bitconf2019 - Closebitconf2019 - Close
bitconf2019 - Close
 
bitconf 2019
bitconf 2019bitconf 2019
bitconf 2019
 
bITconf -close
bITconf -closebITconf -close
bITconf -close
 
bITconf - Intro
bITconf - IntrobITconf - Intro
bITconf - Intro
 
bITconf prezentacja
bITconf prezentacja bITconf prezentacja
bITconf prezentacja
 
apache camel
apache camelapache camel
apache camel
 

Benchmarking

  • 2. Benchmarking • Po co nam Benchmarki • Typowe problemy w mierzeniu wydajności kodu • Narzędzia pozwalające na porównywanie wydajności
  • 3. Po co nam Benchmarki • Porównywanie wydajności alternatywnych rozwiązań • Sprawdzanie wydajności bez konieczności budowy całego rozwiązania • Eksperymentowanie z nowymi rozwiązaniami
  • 4. Rodzaje benchmarków • Makro Benchmarki • Porównywanie dużych funkcjonalności • Całe procesy • Całe systemy • Cała JVM • Mikro Benchmarki • Niewielki kawałki kodu • Krótki czas wykonania
  • 5. Co w tym trudnego? long start = System.currentTimeMillis(); work(); System.out.println( System.currentTimeMillis() - start);
  • 6. Co może pójść nie tak? • Pomiar czasu • Optymalizacje kompilatora • Warm up • Różnice platform
  • 7. Pomiar czasu • Ziarnistość pomiaru czasu (~30 ns Linux, ~300 ns Windows [1t]) • Ukryty narzut System.nanoTime(); • Błąd pomiaru • różnice w implementacji timerów w systemach operacyjnych
  • 8. Optymalizacje kompilatora - pętle • Rozwijanie pętli • Piplineing long start = System.nanoTime(); for (int i = 0; i < 100000; i++) { work(); } System.out.println((System.nanoTime() - start)/100000);
  • 9. Optymalizacje kompilatora – Constant Folding public int measuredMethod(){ // start measurement return 42 + work(); // end of measurement }
  • 10. Optymalizacje kompilatora – False Sharing int someCounter; int completelyDifferentCounter; // on Thread 1 public int measuredMethod1(){ return work(someCounter); } // on Thread 2 public int measuredMethod2(){ return work(completelyDifferentCounter); }
  • 11. Warm up • -XX:CompileThreshold=[1500,2000,10000] • -XX:-PrintCompilation • -XX:MaxInlineSize=35 • -XX:+PrintInlining • -XX:LoopUnrollLimit=n
  • 12. Różnice systemów operacyjnych • Różnice w implementacji JVM • Różnice timerów • Różnice scheduler’ów • 32 vs 64 bit • Niektóre optymalizacje dostępne są dla wybranych OS’ów • Niektóre bug’i też ;)
  • 14. Czym jest JMH i jak może pomóc • Narzędzie do budowania benchmarków • Pomaga w uniknięciu typowych problemów • Nie zwalnia z myślenia o nich. • Java -> org.openjdk.jmh:jmh-java-benchmark-archetype • Scala -> org.openjdk.jmh:jmh-scala-benchmark-archetype -> sbt-jmh plugin • Groovy -> org.openjdk.jmh:jmh-groovy-benchmark- archetype • Kotlin -> org.openjdk.jmh:jmh-java-benchmark-archetype
  • 15. Nowy benchmark package pl.itkontekst.jmhtest; import org.openjdk.jmh.annotations.Benchmark; public class MyBenchmark { @Benchmark public void testMethod(){ } }
  • 16. # JMH 1.14.1 (released 13 days ago) # VM version: JDK 1.8.0_77, VM 25.77-b03 # VM invoker: C:Program FilesJavajre1.8.0_77binjava.exe # VM options: <none> # Warmup: 20 iterations, 1 s each # Measurement: 20 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: pl.itkontekst.jmhtest.MyBenchmark.testMethod # Run progress: 0,00% complete, ETA 00:06:40 # Fork: 1 of 10 # Warmup Iteration 1: 3321638210,400 ops/s # Warmup Iteration 2: 3035709856,963 ops/s … Iteration 19: 3292590873,371 ops/s Iteration 20: 3352591339,138 ops/s Result "testMethod": 3336940878,008 ?(99.9%) 21593035,964 ops/s [Average] (min, avg, max) = (2837336846,716, 3336940878,008, 3433712311,191), stdev = 91426266,353 CI (99.9%): [3315347842,045, 3358533913,972] (assumes normal distribution) # Run complete. Total time: 00:06:43 Benchmark Mode Cnt Score Error Units MyBenchmark.testMethod thrpt 200 3336940878,008 ? 21593035,964 ops/s
  • 17. Opcje pomiarów @Fork(1) @Warmup(iterations = 5) @Measurement(iterations = 5) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class MyBenchmark { @Benchmark public void testMethod() { } }
  • 18. Klasy Stanu, setup, parametry, Black Hole @State(Scope.Benchmark) public static class MyState { @Param({"1","2","3"}) int value; @Setup public void init(){} } @Benchmark public void testAdd(Blackhole blackhole,MyState state) { blackhole.consume(state.value+state.value); Blackhole.consumeCPU(10); } @Benchmark public void testMethod(Blackhole blackhole) { Blackhole.consumeCPU(10); }
  • 19. Wątki, Grupy, Padding @Threads(4) public class MyBenchmark { @State(Scope.Benchmark) public static class MyState { @Param({"2"}) int value; } @State(Scope.Benchmark) public static class MyState2 { @Param({"1"}) int value2; } @Benchmark @Group("add") public void testAdd(Blackhole blackhole,MyState state) { blackhole.consume(state.value+state.value); } @Benchmark @Group("add") public void testAdd2(Blackhole blackhole,MyState2 state) { blackhole.consume(state.value2+state.value2); } }
  • 20. Kontrola pracy kompilatora @CompilerControl(CompilerControl.Mode.DONT_INLINE) public void testDontInline(){} @CompilerControl(CompilerControl.Mode.INLINE) public void testForceInline(){} @CompilerControl(CompilerControl.Mode.EXCLUDE) public void testDontCompile(){}
  • 21. Programowa kontrola uruchamiania public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(MyBenchmark.class.getSimpleName()) .warmupIterations(1) .measurementIterations(3) .forks(1) .build(); new Runner(opt).run(); }
  • 22. Profilery java -jar benchmarks.jar -lprof Supported profilers: cl: Classloader profiling via standard MBeans comp: JIT compiler profiling via standard MBeans gc: GC profiling via standard MBeans hs_cl: HotSpot (tm) classloader profiling via implementation-specific MBeans hs_comp: HotSpot (tm) JIT compiler profiling via implementation-specific MBeans hs_gc: HotSpot (tm) memory manager (GC) profiling via implementation-specific MBeans hs_rt: HotSpot (tm) runtime profiling via implementation-specific MBeans hs_thr: HotSpot (tm) threading subsystem via implementation-specific MBeans pauses: Pauses profiler perf: Linux perf Statistics perfasm: Linux perf + PrintAssembly Profiler perfnorm: Linux perf statistics, normalized by operation count stack: Simple and naive Java stack profiler Unsupported profilers: xperfasm: <none>
  • 23. Stack profiler Stack profiler: ....[Thread state distributions].................................................................... 97,2% RUNNABLE 2,8% WAITING ....[Thread state: RUNNABLE]........................................................................ 56,8% 58,5% pl.itkontekst.jmhtest.MyBenchmark.testAdd 39,8% 41,0% pl.itkontekst.jmhtest.generated.MyBenchmark_add_jmhTest.testAdd_thrpt_jmhStub 0,3% 0,3% sun.misc.Unsafe.compareAndSwapInt 0,1% 0,1% java.lang.Thread.currentThread 0,1% 0,1% sun.misc.Unsafe.unpark ....[Thread state: WAITING]......................................................................... 2,8% 100,0% sun.misc.Unsafe.park
  • 24. Wyniki java -jar benchmarks.jar -lrf Available formats: text, csv, scsv, json, latex java -jar benchmarks.jar -rff output.csv
  • 25. Podsumowanie • Pisanie Mikro Benchmarków nie jest trywialne • JMH pomaga w unikaniu typowych problemów ale nie zwalnia z myślenia o nich • JMH nie zastąpi ostatecznych testów wydajnościowych • JIT to potężny oręż, który może Ci obciąć rękę kiedy nie będziesz uważny