Skip to content

Commit 31a62ff

Browse files
committed
Add JMH benchmarks for Protobuf message converter
This commit re-generates the protobuf Java classes with a recent version of the protoc binary and adds JMH benchmarks that exercise the message converter for both the reading and writing cases. See gh-29496
1 parent 631a5d1 commit 31a62ff

File tree

6 files changed

+828
-500
lines changed

6 files changed

+828
-500
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2002-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.http.converter.protobuf;
18+
19+
20+
import java.io.IOException;
21+
import java.util.List;
22+
import java.util.Random;
23+
import java.util.stream.Stream;
24+
25+
import org.openjdk.jmh.annotations.Benchmark;
26+
import org.openjdk.jmh.annotations.BenchmarkMode;
27+
import org.openjdk.jmh.annotations.Level;
28+
import org.openjdk.jmh.annotations.Mode;
29+
import org.openjdk.jmh.annotations.Param;
30+
import org.openjdk.jmh.annotations.Scope;
31+
import org.openjdk.jmh.annotations.Setup;
32+
import org.openjdk.jmh.annotations.State;
33+
import org.openjdk.jmh.infra.Blackhole;
34+
35+
import org.springframework.protobuf.Msg;
36+
import org.springframework.protobuf.SecondMsg;
37+
import org.springframework.web.testfixture.http.MockHttpInputMessage;
38+
import org.springframework.web.testfixture.http.MockHttpOutputMessage;
39+
40+
/**
41+
* Benchmarks for the {@link ProtobufHttpMessageConverter}.
42+
*
43+
* @author Brian Clozel
44+
*/
45+
@BenchmarkMode(Mode.Throughput)
46+
public class ProtobufHttpMessageConverterBenchmark {
47+
48+
@Benchmark
49+
public void writeMessages(BenchmarkWriteData data, Blackhole bh) throws IOException {
50+
for (Msg message : data.messages) {
51+
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
52+
data.converter.write(message, ProtobufHttpMessageConverter.PROTOBUF, outputMessage);
53+
bh.consume(outputMessage);
54+
}
55+
}
56+
57+
/**
58+
* Benchmark data holding typical Protobuf messages to be converted to bytes.
59+
*/
60+
@State(Scope.Benchmark)
61+
public static class BenchmarkWriteData {
62+
63+
@Param({"40"})
64+
public int messageCount;
65+
66+
public List<Msg> messages;
67+
68+
public ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter();
69+
70+
71+
@Setup(Level.Trial)
72+
public void createMessages() {
73+
Random random = new Random();
74+
this.messages = Stream.generate(() -> createMessage(random.nextInt())).limit(this.messageCount).toList();
75+
}
76+
77+
private Msg createMessage(int randomValue) {
78+
return Msg.newBuilder().setFoo(String.valueOf(randomValue)).setBlah(SecondMsg.newBuilder().setBlah(randomValue).build()).build();
79+
}
80+
81+
}
82+
83+
84+
@Benchmark
85+
public void readMessages(BenchmarkReadData data, Blackhole bh) throws IOException {
86+
for (byte[] message : data.messages) {
87+
MockHttpInputMessage inputMessage = new MockHttpInputMessage(message);
88+
bh.consume(data.converter.read(Msg.class, inputMessage));
89+
}
90+
}
91+
92+
/**
93+
* Benchmark data holding typical Protobuf messages to be converted to bytes.
94+
*/
95+
@State(Scope.Benchmark)
96+
public static class BenchmarkReadData {
97+
98+
@Param({"40"})
99+
public int messageCount;
100+
101+
public List<byte[]> messages;
102+
103+
public ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter();
104+
105+
@Setup(Level.Trial)
106+
public void createMessages() {
107+
Random random = new Random();
108+
this.messages = Stream.generate(() -> createMessage(random.nextInt())).limit(this.messageCount).toList();
109+
}
110+
111+
private byte[] createMessage(int randomValue) {
112+
return Msg.newBuilder().setFoo(String.valueOf(randomValue)).setBlah(SecondMsg.newBuilder().setBlah(randomValue).build()).build().toByteArray();
113+
}
114+
115+
}
116+
}

0 commit comments

Comments
 (0)