序列化框架对比
背景
最近接到一个需求,涉及到大流量的数据传输,那么就不可避免序列化,正巧我也有想法对最近主流的序列化框架做一次对比。
参数对比的序列化的框架如下,将对 序列化数据字节大小
、序列化\反序列化平均耗时
、序列化\反序列化吞吐量
这三个维度进行对比。
该测试结果可能因为机器原因、框架使用方式、样本数据问题,导致结果不准确。
工程代码见 https://github.com/moyada/java-serializers
框架 | 版本 |
---|---|
avro | 1.8.2 |
hessian | 4.0.60 |
jackson | 2.9.8 |
fastjson | 1.2.57 |
gson | 2.8.5 |
kryo | 4.0.2 |
protobuf | 3.7.1 |
protostuff | 1.5.9 |
这里我对所有框架再进行了一次封装,更方便接入测试,也是一般开发中的正常操作,在序列化框架的使用上主要是参考官方文档。
测试环境
JDK 版本为 1.8.0_191,使用 BenchMark
进行测试,环境参数为
# VM options: -server -Xms2048m -Xmx2048m -XX:+UseTLAB -XX:+UseG1GC
# Warmup: 3 iterations, 40 s each
# Measurement: 5 iterations, 60 s each
# Timeout: 10 min per iteration
# Threads: 10 threads, will synchronize iterations
测试的数据结构如下,数据统一为 {"id": 34501231422, "name": "moyada", "age": 18, "gender": true, "scope": 33.23, "identifies": ["moyada", "people", "person", "animal"], "info": {"haha": "666", "test": "111"}}
。
public class User implements Serializable {
private long id;
private String name;
private int age;
private boolean gender;
private Double scope;
private List<String> identifies;
private Map<String, String> info;
}
序列化后数据对比
框架 | 字节大小 |
---|---|
Avro | 76 |
Protobuf | 76 |
Protostuff | 79 |
Kryo | 109 |
Hessian | 140 |
Gson | 140 |
FastJson | 140 |
Jackson | 153 |
平均耗时对比
序列化平均耗时
框架 | 耗时 | 方差 | 单位时间 |
---|---|---|---|
Avro | 11189.699 | 228.857 | ns |
Fastjson | 8859.637 | 58.009 | ns |
Gson | 14581.029 | 59.314 | ns |
Hessian | 16504.562 | 85.219 | ns |
Jackson | 8795.401 | 48.109 | ns |
Kryo | 12437.866 | 52.945 | ns |
Protobuf | 10775.097 | 147.737 | ns |
Protostuff | 6027.095 | 33.662 | ns |
反序列化平均耗时
框架 | 耗时 | 方差 | 单位时间 |
---|---|---|---|
Avro | 25422.477 | 658.969 | ns |
Fastjson | 8736.501 | 81.286 | ns |
Gson | 10366.847 | 941.759 | ns |
Hessian | 9293.557 | 543.865 | ns |
Jackson | 9594.744 | 103.369 | ns |
Kryo | 9190.082 | 243.400 | ns |
Protobuf | 5455.168 | 120.927 | ns |
Protostuff | 4861.520 | 31.993 | ns |
平均耗时综合对比
吞吐量对比
序列化吞吐量
框架 | 吞吐量 | 方差 | 单位时间 |
---|---|---|---|
Avro | 951.174 | 15.053 | ms |
Fastjson | 1160.132 | 11.835 | ms |
Gson | 711.199 | 8.525 | ms |
Hessian | 620.666 | 4.321 | ms |
Jackson | 1215.150 | 19.994 | ms |
Kryo | 836.276 | 16.079 | ms |
Protobuf | 1103.661 | 18.079 | ms |
Protostuff | 1756.591 | 27.101 | ms |
反序列化吞吐量
框架 | 吞吐量 | 方差 | 单位时间 |
---|---|---|---|
Avro | 389.745 | 24.479 | ms |
Fastjson | 1103.777 | 29.458 | ms |
Gson | 977.951 | 38.406 | ms |
Hessian | 1153.816 | 44.385 | ms |
Jackson | 1072.346 | 12.922 | ms |
Kryo | 1098.548 | 33.257 | ms |
Protobuf | 1847.549 | 43.935 | ms |
Protostuff | 2055.013 | 61.317 | ms |
吞吐量综合对比
总结
综合对比下来,抛开未采样的内存占用及 cpu 消耗,大部分序列化框架效率还是比较不错的。
Avro
在反序列化时耗时比较严重,怀疑是否因为多线程而导致的,并且在反序列化后 map 数据还发生了顺序变化。
Protostuff
在各方面都优于其他框架,但是需要预先定义类,不过比起 Protobuf
、Thrift
等预先定义数据格式已经方便很多了。
如果传输量不是很大,但是对数据的可视化有要求的,那么 Fastjson
和 Jackson
是不错的选择,而且 json
格式在跨语言上也天然有优势。