Skip to content

Commit d03d076

Browse files
Add multiGRPC benchmark and ecdsa on GRPC and impove the plots
Signed-off-by: Said Altury <Said.Altury@ibm.com>
1 parent c7c9cea commit d03d076

File tree

6 files changed

+136
-31
lines changed

6 files changed

+136
-31
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
.vscode
44
.build
55
*.iml
6-
6+
.venv
77
# ignoring all generated artifacts in integration tests
88
integration/**/out/
99

integration/benchmark/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ If we want to study the impact of different GC settings we can run the following
3636

3737
```bash
3838
GOGC=100 go test -bench=. -benchmem -count=10 -timeout=20m -cpu=1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,48,64 -run=^$ ./... > plots/benchmark_gc_100.txt
39-
GOGC=off go test -bench=. -benchmem -count=10 -timeout=20m -cpu=1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,48,64 -run=^$ ./... > plots/benchmark_gc_100.txt
39+
GOGC=off go test -bench=. -benchmem -count=10 -timeout=20m -cpu=1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,48,64 -run=^$ ./... > plots/benchmark_gc_off.txt
4040
GOGC=8000 go test -bench=. -benchmem -count=10 -timeout=20m -cpu=1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,48,64 -run=^$ ./... > plots/benchmark_gc_8000.txt
4141
```
4242

integration/benchmark/grpc/grpc_bench_test.go

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import (
2323
"go.opentelemetry.io/otel/trace/noop"
2424
)
2525

26-
func BenchmarkGRPC(b *testing.B) {
27-
srvEndpoint := setupServer(b)
26+
func BenchmarkGRPCSingleConnectionCPU(b *testing.B) {
27+
srvEndpoint := setupServer(b, "cpu")
28+
b.ResetTimer()
2829

2930
// we share a single connection among all client goroutines
3031
cli, closeF := setupClient(b, srvEndpoint)
@@ -40,7 +41,60 @@ func BenchmarkGRPC(b *testing.B) {
4041
benchmark.ReportTPS(b)
4142
}
4243

43-
func setupServer(tb testing.TB) string {
44+
func BenchmarkGRPCMultiConnectionCPU(b *testing.B) {
45+
srvEndpoint := setupServer(b, "cpu")
46+
b.ResetTimer()
47+
48+
b.RunParallel(func(pb *testing.PB) {
49+
// each goroutine gets its own client + connection
50+
cli, closeF := setupClient(b, srvEndpoint)
51+
defer closeF()
52+
53+
for pb.Next() {
54+
resp, err := cli.CallViewWithContext(b.Context(), "fid", nil)
55+
require.NoError(b, err)
56+
require.NotNil(b, resp)
57+
}
58+
})
59+
60+
benchmark.ReportTPS(b)
61+
}
62+
63+
// --- ECDSA Workload Benchmarks ---
64+
65+
func BenchmarkGRPCSingleConnectionECDSA(b *testing.B) {
66+
srvEndpoint := setupServer(b, "ecdsa")
67+
b.ResetTimer()
68+
69+
cli, closeF := setupClient(b, srvEndpoint)
70+
defer closeF()
71+
b.RunParallel(func(pb *testing.PB) {
72+
for pb.Next() {
73+
resp, err := cli.CallViewWithContext(b.Context(), "fid", nil)
74+
require.NoError(b, err)
75+
require.NotNil(b, resp)
76+
}
77+
})
78+
benchmark.ReportTPS(b)
79+
}
80+
81+
func BenchmarkGRPCMultiConnectionECDSA(b *testing.B) {
82+
srvEndpoint := setupServer(b, "ecdsa")
83+
b.ResetTimer()
84+
b.RunParallel(func(pb *testing.PB) {
85+
cli, closeF := setupClient(b, srvEndpoint)
86+
defer closeF()
87+
88+
for pb.Next() {
89+
resp, err := cli.CallViewWithContext(b.Context(), "fid", nil)
90+
require.NoError(b, err)
91+
require.NotNil(b, resp)
92+
}
93+
})
94+
benchmark.ReportTPS(b)
95+
}
96+
97+
func setupServer(tb testing.TB, workloadType string) string {
4498
tb.Helper()
4599

46100
mDefaultIdentity := view.Identity("server identity")
@@ -80,10 +134,21 @@ func setupServer(tb testing.TB) string {
80134
require.NoError(tb, err)
81135
require.NotNil(tb, srv)
82136

83-
parms := &benchviews.CPUParams{N: 200000}
84-
input, _ := json.Marshal(parms)
85-
factory := &benchviews.CPUViewFactory{}
86-
v, _ := factory.NewView(input)
137+
var v view.View
138+
switch workloadType {
139+
case "cpu":
140+
parms := &benchviews.CPUParams{N: 200000}
141+
input, _ := json.Marshal(parms)
142+
factory := &benchviews.CPUViewFactory{}
143+
v, _ = factory.NewView(input)
144+
case "ecdsa":
145+
parms := &benchviews.ECDSASignParams{}
146+
input, _ := json.Marshal(parms)
147+
factory := &benchviews.ECDSASignViewFactory{}
148+
v, _ = factory.NewView(input)
149+
default:
150+
tb.Fatalf("unknown workload type: %s", workloadType)
151+
}
87152

88153
// our view manager
89154
vm := &benchmark.MockViewManager{Constructor: func() view.View {

integration/benchmark/grpc/view_bench_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
)
1515

1616
func BenchmarkView(b *testing.B) {
17-
srvEndpoint := setupServer(b)
17+
srvEndpoint := setupServer(b, "cpu")
1818

1919
// we share a single connection among all client goroutines
2020
cli, closeF := setupClient(b, srvEndpoint)

integration/benchmark/plots/plot.py

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,42 @@
1616
INPUT_FILE = sys.argv[1]
1717
OUTPUT_PDF = sys.argv[2]
1818

19+
# ----------------------------
20+
# EXTRACT GOGC FROM FILENAME
21+
# ----------------------------
22+
#
23+
# Expected filenames:
24+
# benchmark_gc_100.txt
25+
# benchmark_gc_off.txt
26+
#
27+
# ----------------------------
28+
29+
gc_match = re.search(r"benchmark_gc_([^./]+)", INPUT_FILE)
30+
if gc_match:
31+
GOGC_LABEL = f"GOGC={gc_match.group(1)}"
32+
else:
33+
GOGC_LABEL = "GOGC=unknown"
34+
1935
# ----------------------------
2036
# PARSING LOGIC
2137
# ----------------------------
2238
#
23-
# We need to extract:
24-
# - benchmark group name (e.g. "BenchmarkSimple/parallel")
39+
# We extract:
40+
# - benchmark group name
2541
# - worker count (default = 1)
26-
# - TPS value
42+
# - TPS values
2743
#
2844
# ----------------------------
2945

30-
# dictionary:
3146
# group_name → { worker → [tps runs] }
3247
groups = defaultdict(lambda: defaultdict(list))
3348

34-
# Matches all forms:
35-
# BenchmarkSimple/parallel-4 ... 140240 TPS
36-
# BenchmarkParallelWork-12 ... 13246 TPS
37-
pattern = re.compile(r"(Benchmark[^\s/-]+(?:/[^\s/-]+)?)" # group name
38-
r"(?:-(\d+))?" # optional worker/cpu suffix
39-
r".*?([\d.]+)\s+TPS", re.IGNORECASE)
49+
pattern = re.compile(
50+
r"(Benchmark(?:[^\s/-]+)?(?:/[^\s/-]+)*)" # group name
51+
r"(?:-(\d+))?" # optional worker suffix
52+
r".*?([\d.]+)\s+TPS",
53+
re.IGNORECASE,
54+
)
4055

4156
with open(INPUT_FILE, "r") as f:
4257
for line in f:
@@ -49,14 +64,15 @@
4964
tps = float(m.group(3))
5065

5166
worker = int(worker_str) if worker_str else 1
52-
5367
groups[group][worker].append(tps)
5468

55-
with PdfPages(OUTPUT_PDF) as pdf:
69+
# ----------------------------
70+
# PLOTTING
71+
# ----------------------------
5672

73+
with PdfPages(OUTPUT_PDF) as pdf:
5774
for group_name, worker_dict in sorted(groups.items()):
5875

59-
# Sort and compute stats
6076
worker_counts = sorted(worker_dict.keys())
6177
tps_means = [np.mean(worker_dict[c]) for c in worker_counts]
6278
tps_stddev = [np.std(worker_dict[c]) for c in worker_counts]
@@ -65,18 +81,26 @@
6581
print(" Worker counts:", worker_counts)
6682
print(" TPS means:", tps_means)
6783

68-
# -------------
69-
# Plot 1: TPS
70-
# -------------
71-
7284
plt.figure(figsize=(10, 6))
73-
plt.errorbar(worker_counts, tps_means, yerr=tps_stddev, fmt="o-", capsize=6)
85+
plt.errorbar(
86+
worker_counts,
87+
tps_means,
88+
yerr=tps_stddev,
89+
fmt="o-",
90+
capsize=6,
91+
)
92+
7493
plt.xlabel("Worker Count")
7594
plt.ylabel("Average TPS")
76-
plt.title(f"{group_name}")
95+
96+
# Benchmark name + GC config in header
97+
plt.title(group_name)
98+
plt.suptitle(GOGC_LABEL, fontsize=12, fontweight="bold", y=0.98)
99+
77100
plt.grid(True)
78-
plt.tight_layout()
101+
plt.tight_layout(rect=[0, 0, 1, 0.95])
102+
79103
pdf.savefig()
80104
plt.close()
81105

82-
print(f"\nSaved multi-benchmark PDF to: {OUTPUT_PDF}")
106+
print(f"\nSaved multi-benchmark PDF to: {OUTPUT_PDF}")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
PLOT_SCRIPT="plot.py"
5+
6+
for txt in benchmark_gc_*.txt; do
7+
# Strip .txt extension
8+
base="${txt%.txt}"
9+
pdf="${base}.pdf"
10+
11+
echo "Generating ${pdf} from ${txt}"
12+
13+
python3 "${PLOT_SCRIPT}" "${txt}" "${pdf}"
14+
done
15+
16+
echo "All plots generated ✔"

0 commit comments

Comments
 (0)