JSON解析工具对比:FastJson、Jackson、Gson、Hutool的性能评测与排行

JSON解析工具对比:FastJson、Jackson、Gson、Hutool的性能评测与排行

在当今的项目中,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依赖:

org.openjdk.jmh

jmh-core

1.36

org.openjdk.jmh

jmh-generator-annprocess

1.36

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依赖:

com.alibaba.fastjson2

fastjson2

2.0.52

com.alibaba

fastjson

1.2.83

com.fasterxml.jackson.core

jackson-core

2.17.2

com.fasterxml.jackson.core

jackson-databind

2.17.2

com.google.code.gson

gson

2.11.0

cn.hutool

hutool-json

5.8.23

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 users;

@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解析性能排行榜

相关拼贴