-
Notifications
You must be signed in to change notification settings - Fork 0
/
async_profiler_demo.java
141 lines (112 loc) · 4.06 KB
/
async_profiler_demo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 20+
//DEPS org.openjdk.jmh:jmh-generator-annprocess:1.36
//DEPS tools.profiler:async-profiler:2.9
//JAVA_OPTIONS --add-opens java.base/java.lang=ALL-UNNAMED
//RUNTIME_OPTIONS --enable-preview -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints
// to run with javagagent add the following:
// `--javaagent=ap-loader@maxandersen=start,event=cpu,file=profile.html,flamegraph`
// OR
// `--javaagent=ap-loader@jvm-profiling-tools/ap-loader=start,event=cpu,file=profile.html,flamegraph`
//READ https://krzysztofslusarski.github.io/2022/12/12/async-manual.html
package foo;
import one.profiler.AsyncProfiler;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.stream.Stream;
import static foo.asyn_prof_demo.Profiler.EventType.*;
import static foo.asyn_prof_demo.Profiler.Type.FLAME;
import static foo.asyn_prof_demo.Profiler.Type.JFR;
import static java.lang.System.out;
/**
* Demo how to start async profiler programmatically
* with jbang
*/
public class async_profiler_demo {
public static void main(String... args) {
var test = new SquaredSum();
long limit = 1000000;
var ints = Stream.iterate(1, i -> i + 1).limit(limit).mapToInt(i -> i).toArray();
var dbls = Stream.iterate(1, i -> i + 1).limit(limit).mapToDouble(i -> i).toArray();
var bdcs = Stream.iterate(1, i -> i + 1).limit(limit).map(BigDecimal::valueOf).toArray(BigDecimal[]::new);
var profiler = new Profiler(FLAME, CPU, "async_prof_result");
profiler.start();
out.println("integers " + test.sumIntegers(ints));
out.println("doubles " + test.sumDoubles(dbls));
out.println("bigdecimals " + test.sumBigDecimals(bdcs));
profiler.stop();
}
static class Profiler {
private String file;
private String command = "";
enum Type {JFR, FLAME}
enum EventType {CPU("cpu"), WALL("wall"), ALLOC("alloc"), LOCK("lock"), CACHE_MISSES("cache-misses");
private final String asString;
EventType(String s) {
this.asString = s;
}
@Override
public String toString() {
return asString;
}
}
AsyncProfiler profiler = AsyncProfiler.getInstance();
Profiler(Type type, EventType eventType, String filename) {
command = type == JFR ? "jfr," : "";
command += "event=%s".formatted(eventType);
file = "_%s".formatted(eventType);
file = type == JFR ? filename + file + ".jfr" : filename + file + ".html";
}
void start() {
try {
profiler.execute(String.format("start,%s,file=%s", command, file));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
void stop() {
try {
profiler.execute(String.format("stop,file=%s", file));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* doesn't matter just spend some wall and cpu time
*/
static class SquaredSum {
int sumIntegers(int[] arr) {
sleep(1);
int sum = 0;
for (int j : arr) {
sum += j * j;
}
return sum;
}
private static void sleep(int i) {
try {
Thread.sleep(i * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
double sumDoubles(double[] arr) {
sleep(2);
double sum = 0;
for (double v : arr) {
sum += v * v;
}
return sum;
}
BigDecimal sumBigDecimals(BigDecimal[] arr) {
sleep(5);
BigDecimal sum = BigDecimal.ZERO;
for (BigDecimal bigDecimal : arr) {
sum = sum.add(bigDecimal.multiply(bigDecimal));
}
return sum;
}
}
}