diff --git a/protocol/pom.xml b/protocol/pom.xml
index 247e7f3c1..a5100bcea 100644
--- a/protocol/pom.xml
+++ b/protocol/pom.xml
@@ -122,6 +122,21 @@
3.0.2
+
+
+ org.openjdk.jmh
+ jmh-core
+ 1.37
+ test
+
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ 1.37
+ test
+
+
com.esotericsoftware
kryo
diff --git a/protocol/src/test/java/com/zfoo/protocol/BenchmarkTesting.java b/protocol/src/test/java/com/zfoo/protocol/BenchmarkTesting.java
index 01973c28e..2928f1864 100644
--- a/protocol/src/test/java/com/zfoo/protocol/BenchmarkTesting.java
+++ b/protocol/src/test/java/com/zfoo/protocol/BenchmarkTesting.java
@@ -189,8 +189,6 @@ public void jsonbTest() {
// 序列化和反序列化简单对象
long startTime = System.currentTimeMillis();
for (int i = 0; i < benchmark; i++) {
- input.reset();
- output.reset();
var bytes = JSONB.toBytes(simpleObject);
var mess = JSONB.parseObject(bytes, SimpleObject.class);
@@ -204,8 +202,6 @@ public void jsonbTest() {
// 序列化和反序列化常规对象
startTime = System.currentTimeMillis();
for (int i = 0; i < benchmark; i++) {
- input.reset();
- output.reset();
var bytes = JSONB.toBytes(normalObject);
var mess = JSONB.parseObject(bytes, NormalObject.class);
}
@@ -215,9 +211,6 @@ public void jsonbTest() {
// 序列化和反序列化复杂对象
startTime = System.currentTimeMillis();
for (int i = 0; i < benchmark; i++) {
- input.reset();
- output.reset();
-
var bytes = JSONB.toBytes(complexObject);
var mess = JSONB.parseObject(bytes, ComplexObject.class);
}
@@ -413,7 +406,7 @@ protected Kryo initialValue() {
}
}
- private static ThreadSafeFury fury;
+ public static ThreadSafeFury fury;
static {
fury = new ThreadLocalFury(classLoader -> {
diff --git a/protocol/src/test/java/com/zfoo/protocol/JmhBenchmark.java b/protocol/src/test/java/com/zfoo/protocol/JmhBenchmark.java
new file mode 100644
index 000000000..f5e73d3f4
--- /dev/null
+++ b/protocol/src/test/java/com/zfoo/protocol/JmhBenchmark.java
@@ -0,0 +1,143 @@
+package com.zfoo.protocol;
+
+import com.alibaba.fastjson2.JSONB;
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import com.google.protobuf.CodedInputStream;
+import com.google.protobuf.CodedOutputStream;
+import com.zfoo.protocol.packet.ComplexObject;
+import com.zfoo.protocol.packet.NormalObject;
+import com.zfoo.protocol.packet.ProtobufObject;
+import com.zfoo.protocol.packet.SimpleObject;
+import io.fury.ThreadSafeFury;
+import io.fury.memory.MemoryBuffer;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.buffer.UnpooledHeapByteBuf;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.results.format.ResultFormatType;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.io.IOException;
+
+
+/**
+ * @author godotg
+ */
+@Ignore
+public class JmhBenchmark {
+
+ public static final BenchmarkTesting benchmark = new BenchmarkTesting();
+ public static final SimpleObject simpleObject = BenchmarkTesting.simpleObject;
+ public static final NormalObject normalObject = BenchmarkTesting.normalObject;
+ public static final ComplexObject complexObject = BenchmarkTesting.complexObject;
+ // zfoo
+ public static final ByteBuf buffer = new UnpooledHeapByteBuf(ByteBufAllocator.DEFAULT, 100, 1_0000);
+ // fury
+ public static final ThreadSafeFury fury = BenchmarkTesting.fury;
+ public static final MemoryBuffer bufferFury = MemoryBuffer.newHeapBuffer(1_0000);
+ // kryo
+ public static final Output output = new Output(1024 * 8);
+ public static final Input input = new Input(output.getBuffer());
+ public static final ThreadLocal kryos = BenchmarkTesting.kryos;
+ // protobuf
+ public static final byte[] bufferProtobuf = new byte[1024 * 8];
+ public static ProtobufObject.ProtobufComplexObject protobufComplexObject = BenchmarkTesting.protobufComplexObject;
+ public static ProtobufObject.ProtobufNormalObject protobufNormalObject = BenchmarkTesting.protobufNormalObject;
+ public static ProtobufObject.ProtobufSimpleObject protobufSimpleObject = BenchmarkTesting.protobufSimpleObject;
+
+ @Benchmark
+ public void zfooTest() {
+ buffer.clear();
+ ProtocolManager.write(buffer, simpleObject);
+ var simple = ProtocolManager.read(buffer);
+ buffer.clear();
+ ProtocolManager.write(buffer, normalObject);
+ var normal = ProtocolManager.read(buffer);
+ buffer.clear();
+ ProtocolManager.write(buffer, complexObject);
+ var complex = ProtocolManager.read(buffer);
+ }
+
+ @Benchmark
+ public void furyTest() {
+ bufferFury.writerIndex(0);
+ bufferFury.readerIndex(0);
+ fury.serialize(bufferFury, simpleObject);
+ var simple = fury.deserialize(bufferFury);
+ bufferFury.writerIndex(0);
+ bufferFury.readerIndex(0);
+ fury.serialize(bufferFury, normalObject);
+ var normal = fury.deserialize(bufferFury);
+ bufferFury.writerIndex(0);
+ bufferFury.readerIndex(0);
+ fury.serialize(bufferFury, complexObject);
+ var complex = fury.deserialize(bufferFury);
+ }
+
+ @Benchmark
+ public void jsonbTest() {
+ var bytes = JSONB.toBytes(simpleObject);
+ var simple = JSONB.parseObject(bytes, SimpleObject.class);
+ bytes = JSONB.toBytes(normalObject);
+ var normal = JSONB.parseObject(bytes, NormalObject.class);
+ bytes = JSONB.toBytes(complexObject);
+ var complex = JSONB.parseObject(bytes, ComplexObject.class);
+ }
+
+ @Benchmark
+ public void kryoTest() {
+ var kryo = kryos.get();
+ input.reset();
+ output.reset();
+ kryo.writeObject(output, simpleObject);
+ var simple = kryo.readObject(input, SimpleObject.class);
+ input.reset();
+ output.reset();
+ kryo.writeObject(output, normalObject);
+ var normal = kryo.readObject(input, NormalObject.class);
+ input.reset();
+ output.reset();
+ kryo.writeObject(output, complexObject);
+ var complex = kryo.readObject(input, ComplexObject.class);
+ }
+
+ @Benchmark
+ public void protobufTest() throws IOException {
+ var codedOutputStream = CodedOutputStream.newInstance(bufferProtobuf);
+ protobufSimpleObject.writeTo(codedOutputStream);
+ var length = codedOutputStream.getTotalBytesWritten();
+ var codeInput = CodedInputStream.newInstance(bufferProtobuf, 0, length);
+ var simple = ProtobufObject.ProtobufSimpleObject.parseFrom(codeInput);
+
+ codedOutputStream = CodedOutputStream.newInstance(bufferProtobuf);
+ protobufNormalObject.writeTo(codedOutputStream);
+ length = codedOutputStream.getTotalBytesWritten();
+ codeInput = CodedInputStream.newInstance(bufferProtobuf, 0, length);
+ var normal = ProtobufObject.ProtobufNormalObject.parseFrom(codeInput);
+
+ codedOutputStream = CodedOutputStream.newInstance(bufferProtobuf);
+ protobufComplexObject.writeTo(codedOutputStream);
+ length = codedOutputStream.getTotalBytesWritten();
+ codeInput = CodedInputStream.newInstance(bufferProtobuf, 0, length);
+ var complex = ProtobufObject.ProtobufComplexObject.parseFrom(codeInput);
+ }
+
+ @Test
+ public void test() throws RunnerException {
+ // upload jmh-result.json to the following website in order to generate chart
+ // https://deepoove.com/jmh-visual-chart/
+ Options opt = new OptionsBuilder()
+ .include(JmhBenchmark.class.getSimpleName())
+ .resultFormat(ResultFormatType.JSON)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+}
\ No newline at end of file