在当今的项目中,JSON格式数据的使用越来越广泛,几乎无处不在。对JSON数据进行压缩不仅能显著降低存储和带宽成本,还能在数据格式转换时节省CPU计算资源。因此,JSON数据的转换速度直接影响接口响应时间以及系统吞吐量。为此,本文将对市面上主流的五种JSON解析工具——FastJson、FastJson2、Jackson、Gson 和 Hutool-JSON,利用JAVA基准测试对小、中、大JSON的序列化和反序列化进行六项指标的测试,最后提供一个性能排行榜,希望能为您在选择JSON工具时提供参考。
2.1 JMH基准测试
在进行代码性能测试时,常见的简单方法是记录代码执行前后的时间差。然而,这种方法的准确性受到多种因素的影响,可能导致测试结果不稳定。为确保测试的准确性,本次使用了JMH(Java Microbenchmark Harness)工具,它是由OpenJDK/Oracle维护的,旨在帮助开发人员编写可靠的基准测试并规避常见误区。使用JMH进行的测试结果具备更高的说服力。
添加JMH Maven依赖:
JMH测试代码:
@State(Scope.Thread)
public class HelloBenchmark {
@Benchmark
public void testMethod() throws InterruptedException {
Thread.sleep(10);
}
@Test
public void testBenchmark() throws Exception {
Options options = new OptionsBuilder()
.include(HelloBenchmark.class.getSimpleName())
.forks(1) //进程数
.threads(1) //线程数
.warmupIterations(1)
.measurementIterations(1)
.mode(Mode.Throughput)
.build();
new Runner(options).run();
}
}
JMH测试结果:
Benchmark Mode Score Units
testMethod thrpt 64.579 ops/s
2.2 测试JSON工具的版本
相同工具的不同版本在性能上可能存在显著差异。本文选取了当前主流版本进行测试,测试结果仅适用于以下版本:
Tool版本FastJson22.0.52FastJson1.2.83Jackson2.17.2Gson2.11.0Hutool5.8.23
以下为各工具版本对应的Maven依赖:
2.3 测试平台
测试结果受JDK版本和运行环境的影响,因此不同机器的得分差异可能显著。以下是我的测试环境配置:
硬件: MacBook Pro 16GB 13英寸 M2 2022 macOS Ventura 13.5.1 (22G90)
JDK: Azul Zulu 17.0.8 - aarch64
IDE: IntelliJ IDEA 2024.2 (Ultimate Edition)
2.4 测试代码
在测试中,我将针对 小JSON、中JSON 和 大JSON 进行序列化和反序列化的性能评分。在此,我对小、中、大JSON的定义如下:
小JSON
在每个系统中,用户信息是最常见的,因此我选取用户详情接口返回的用户信息JSON作为小JSON进行测试,用户对象的定义如下:
@Data
public class User {
private Long id;
private String name;
private String trueName;
private Integer age;
private String sex;
private Date createTime;
}
中JSON
在实际项目中,除了获取用户详情接口外,获取列表接口也非常常见。一般分页返回的数据条数为10条或20条,因此我选取20条用户信息作为中JSON的测试数据,这种数据具备代表性。中JSON的数据定义如下:
private List
@Setup
public void setup() {
users = new ArrayList<>();
IntStream.range(1, 20).forEach(x -> {
User user = new User();
user.setId(1L);
user.setName(RandomUtil.randomString("公众号:赵侠客",100));
user.setAge(29);
user.setSex("男");
user.setTrueName(RandomUtil.randomString("公众号:赵侠客",100));
user.setCreateTime(new Date());
users.add(user);
});
}
大JSON
在各个项目中,大JSON的定义各有不同。以博客系统为例,我认为大JSON可能是文章正文中的HTML富文本数据。因此在测试数据中,我选取公众号文章详情页的HTML富文本数据作为大JSON。大JSON对象的定义如下:
@Data
public class Article {
private Long id;
private String author;
private Long tenantId;
private String title;
private String subTitle;
private String htmlContent;
private Date publishTime;
}
@Setup
public void setup() throws IOException {
article = new Article();
article.setId(10000L);
article.setTenantId(10000L);
article.setAuthor("公众号:赵侠客");
article.setPublishTime(new Date());
article.setTitle(RandomUtil.randomString("主标题", 100));
article.setSubTitle(RandomUtil.randomString("副标题", 50));
article.setHtmlContent(new String(Files.readAllBytes(Paths.get("article.html"))));
}
大JSON部分数据内容
定义完小JSON、中JSON、大JSON后,就可以使用JMH进行基准测试,以下是小JSON序列化的测试代码:
@State(Scope.Thread)
public class SmallJsonSerialize {
private User user;
private ObjectMapper mapper;
private Gson gson;
@Setup
public void setup() {
user = new User();
user.setId(1L);
user.setName("赵侠客");
user.setAge(29);
user.setSex("男");
user.setTrueName("公众号");
user.setCreateTime(new Date());
mapper = new ObjectMapper();
gson = new Gson();
}
@TearDown
public void tearDown() {
user = null;
mapper = null;
gson = null;
}
@Benchmark
public void testFastJson() {
String json = JSON.toJSONString(user);
}
@Benchmark
public void testFast2Json() {
String json = com.alibaba.fastjson2.JSON.toJSONString(user);
}
@Benchmark
public void testHutoolJson() {
String json = JSONUtil.toJsonStr(user);
}
@Benchmark
public void testJackson() throws JsonProcessingException {
String json = mapper.writeValueAsString(user);
}
@Benchmark
public void testGson() {
String json = gson.toJson(user);
}
@Test
public void testBenchmark() throws Exception {
Options options = new OptionsBuilder()
.include(SmallJsonSerialize.class.getSimpleName())
.forks(1)
.threads(1)
.warmupIterations(1)
.measurementIterations(1)
.mode(Mode.Throughput)
.build();
new Runner(options).run();
}
}
3.1 小JSON序列化测试
3.1.1 小JSON序列化跑分:
Benchmark Score Units
FastJson2 13653527.046 ops/s
FastJson 8502829.931 ops/s
Gson 1217934.274 ops/s
HutoolJson 437293.524 ops/s
Jackson 5779830.068 ops/s
从结果来看,小JSON的序列化非常快速,HTTP接口的响应时间通常在几十毫秒到几秒之间,因此对小JSON的序列化不会显著影响接口性能。如果您的项目中仅有小JSON的场景,那么选择工具时可以相对随意,重点可以放在业务逻辑上而无需过于纠结JSON工具的选择。然而,作为技术爱好者,我将对五种工具的得分进行排名,Score为JMH的跑分。
百分制:最大Score的得100分,其它为 100*(Score/最大值)
3.1.2 小JSON序列化排名:
ToolScore百分制FastJson213653527100FastJson850282962.3Jackson577983042.3Gson12179348.9Hutool4372933.2
根据这个排名,我有两点想说:
FastJson2,无敌是多么,多么寂寞。
Hutool,@所有人,大家看看项目中有没有使用Hutool-Json,如果有请到我办公室。
3.2 中JSON序列化测试
3.2.1 中JSON序列化跑分:
Benchmark Score Units
FastJson2 236910.655 ops/s
FastJson 173386.528 ops/s
Gson 50937.391 ops/s
HutoolJson 10928.165 ops/s
Jackson 212457.203 ops/s
对于中JSON的序列化,得分明显下降,最差的Hutool每秒仅能序列化过万次,大约需要0.1毫秒才能完成一次JSON转换。如果接口中存在大量的中JSON序列化调用,将会对响应时间造成一定影响。
3.2.2 中JSON序列化排名:
ToolScore百分制FastJson2236910100Jackson21245789.7FastJson17338673.2Gson5093721.5Hutool109284.6
看到这个排名后,我有两点想说:
FastJson2,无敌是多么,多么空虚。
Hutool,@所有人,大家看看项目中有没有使用Hutool-Json,如果有请到我办公室。
3.3 大JSON序列化测试
3.3.1 大JSON序列化跑分:
Benchmark Score Units
FastJson2 9650.211 ops/s
FastJson 4791.032 ops/s
Gson 5835.649 ops/s
HutoolJson 1035.357 ops/s
Jackson 13398.324 ops/s
在大JSON的序列化中,Hutool的表现最差,每次序列化的时间已经达到1毫秒。我在PC上跑了相同的测试,结果如下:
Benchmark Score Units
Fast2Json 5788.067 ops/s
FastJson 2480.132 ops/s
Gson 2176.535 ops/s
HutoolJson 455.914 ops/s
Jackson 5276.439 ops/s
在Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz上测试的结果显示,Hutool的执行时间最长,每次JSON序列化需要达到2毫秒。因此,大JSON解析的速度对我们的接口性能影响非常明显。
3.3.2 大JSON序列化排名:
ToolScore百分制Jackson13398100FastJson2965072.0Gson583543.6FastJson479135.8Hutool10357.7
根据这个排名,我有两点想说:
Jackson,作为SpringBoot默认的JSON序列化工具,果然名不虚传。
Hutool,@所有人,大家看看项目中有没有使用Hutool-Json,如果有请到我办公室。
4.1 小JSON反序列化测试
4.1.1 小JSON反序列化跑分:
Benchmark Score Units
FastJson2 11654586.191 ops/s
FastJson 5980216.867 ops/s
Gson 2415733.238 ops/s
HutoolJson 855421.710 ops/s
Jackson 3194855.332 ops/s
4.1.2 小JSON反序列化排名:
Tool百分制SDS变化SSFastJson210011654586-14.6%13653527FastJson51.35980216-29.7%8502829Jackson27.43194855+162.3%1217934Gson20.72415733+452.4%437293Hutool7.3855421-85.2%5779830
根据这个排名,我有四点想说:
FastJson2,无敌是多么,多么寂寞。
Jackson & Gson,相比于序列化,反序列化要快得多。
FastJson & FastJson2,你们很强,但却输给了自己。
Hutool,@所有人,大家看看项目中有没有使用Hutool-Json,如果有请到我办公室。
4.2 中JSON反序列化测试
4.2.1 中JSON反序列化跑分:
Benchmark Score Units
FastJson2 691572.756 ops/s
FastJson 495493.338 ops/s
Gson 174852.543 ops/s
HutoolJson 37997.839 ops/s
Jackson 216731.673 ops/s
4.2.2 中JSON反序列化排名:
Tool百分制MDS变化MSFastJson2100691572+191.9%236910FastJson71.6495493+185.8%173386Jackson31.3216731-2.0%212457Gson25.3174852+243.3%50937Hutool5.537997-25.4%50937
根据这个排名,我有三点想说:
FastJson2,无敌是多么,多么空虚。
FastJson2 & FastJson,不仅强大,还比自己序列化更快。
Hutool,@所有人,大家看看项目中有没有使用Hutool-Json,如果有请到我办公室。
4.3 大JSON反序列化测试
4.3.1 大JSON反序列化跑分:
Benchmark Score Units
FastJson2 8555.106 ops/s
FastJson 9002.889 ops/s
Gson 6141.212 ops/s
HutoolJson 1252.990 ops/s
Jackson 4614.815 ops/s
4.3.2 大JSON反序列化排名:
Tool百分制BDS变化BSFastJson1009002+87.9%4791FastJson295.08555-11.3%9650Gson68.26141+5.2%5835Jackson51.34614-65.6%13398Hutool13.91252+20.9%1035
根据这个排名,我有三点想说:
FastJson2,青出于蓝而胜于蓝,但你没想到人家还留了一手。
FastJson,教会徒弟饿死师傅这个道理你是懂的。
Hutool,@所有人,大家看看项目中有没有使用Hutool-Json,如果有请到我办公室。
排行榜
===
Tool排名总分百分制SSMSBSSDSMDSBDSFastJson2状元56710010010072.010010095.0FastJson榜眼394.269.562.373.235.851.371.6100Jackson探花34260.342.389.710027.431.351.3Gson进士188.233.28.921.543.620.725.368.2Hutool孙山42.27.43.24.67.77.35.513.9
JSON解析性能排行榜