Java四大常用JSON解析性能对比:Hutool、Fastjson2、Gson与Jackson测试

Java四大常用JSON解析性能对比:Hutool、Fastjson2、Gson与Jackson测试

1. 引言

JSON 是现代软件开发中常用的数据交换格式,尤其在微服务和前后端分离的架构中更是必不可少。

本文将对 Java 中四大主流 JSON 解析库——Hutool、Fastjson2、Gson 和 Jackson 进行性能测试和对比分析,通过实测 20 万条数据解析,揭示各库在批量和逐条处理中的表现。

测试结果仅供参考!!! 请多次测试再抉择

2. 环境与依赖

2.1 环境信息

操作系统:Window11JDK 版本:jdk1.8.0_281CPU : AMD Ryzen 9 7945HX内存:32GB2.2 Maven依赖

在项目的 pom.xml 文件中引入以下依赖:

com.google.code.gson

gson

2.10.1

com.alibaba.fastjson2

fastjson2

2.0.52

com.fasterxml.jackson.core

jackson-databind

2.14.2

cn.hutool

hutool-all

5.8.35

org.projectlombok

lombok

3. 测试代码

3.1 数据模型

定义一个简单的实体对象:

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

/**

* @author 阿水

*/

@Data

@AllArgsConstructor

@NoArgsConstructor

public class Variable {

private int id;

private String name;

private double value;

private String description;

private String type;

}

3.2 测试数据生成

模拟 20 万条数据用于测试:

// 生成测试数据

public static List generateData(int size) {

List list = new ArrayList<>(size);

for (int i = 0; i < size; i++) {

Variable data = new Variable();

data.setId(i);

data.setName("Name" + i);

data.setValue(Math.random() * 1000);

data.setDescription(IdUtil.fastSimpleUUID());

data.setType(IdUtil.fastSimpleUUID()+i);

list.add(data);

}

return list;

}

3.3 四大库序列化与反序列化测试

import cn.hutool.core.util.IdUtil;

import cn.hutool.json.JSONUtil;

import com.alibaba.fastjson2.JSON;

import com.fasterxml.jackson.core.type.TypeReference;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.google.gson.Gson;

import com.google.gson.reflect.TypeToken;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;

import java.util.List;

import java.util.stream.Collectors;

/**

* @description: JSON 序列化、解析性能测试

* @author 阿水

*/

@Slf4j

public class JsonBenchmarkTest {

//数据总条数

public static int dataSize = 200000;

//测试次数

public static int iterations = 10;

public static void main(String[] args) throws Exception {

// 生成测试数据

List testData = generateData(dataSize);

log.info("测试数据总条数为: {} 条", dataSize);

log.info("以下测试结果均为进行 {} 次计算之后,耗费时间取平均值计算得出。", iterations);

// 序列化测试

String jsonString = serializationTest(testData);

log.info("JSON 数据总大小为: {} 字节", jsonString.length());

// 批量解析测试

log.info("===== 使用批量解析 JSON(即解析集合API)=====");

batchParseTest(jsonString);

// 单条解析测试

log.info("===== 循环遍历逐个解析 JSON API =====");

singleParseTest(jsonString);

// 单条解析并插入集合测试

log.info("===== 循环遍历逐个解析 JSON并插入集合 API=====");

singleParseAndAddListTest(jsonString);

}

// 生成测试数据

public static List generateData(int size) {

List list = new ArrayList<>(size);

for (int i = 0; i < size; i++) {

Variable data = new Variable();

data.setId(i);

data.setName("Name" + i);

data.setValue(Math.random() * 1000);

data.setDescription(IdUtil.fastSimpleUUID());

data.setType(IdUtil.fastSimpleUUID()+i);

list.add(data);

}

return list;

}

/**

* 序列化测试

*/

private static String serializationTest(List testData) throws Exception {

String jsonResult = null;

// Hutool

long hutoolTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

String hutoolJson = JSONUtil.toJsonStr(testData);

long end = System.currentTimeMillis();

hutoolTotal += (end - start);

if (i == 0) jsonResult = hutoolJson; // 保存结果

}

log.info("HuTool 序列化平均耗时: {} ms", hutoolTotal / iterations);

// Fastjson2

long fastjsonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

String fastjsonJson = JSON.toJSONString(testData);

long end = System.currentTimeMillis();

fastjsonTotal += (end - start);

}

log.info("Fastjson2 序列化平均耗时: {} ms", fastjsonTotal / iterations);

// Gson

Gson gson = new Gson();

long gsonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

String gsonJson = gson.toJson(testData);

long end = System.currentTimeMillis();

gsonTotal += (end - start);

}

log.info("Gson 序列化平均耗时: {} ms", gsonTotal / iterations);

// Jackson

ObjectMapper objectMapper = new ObjectMapper();

long jacksonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

String jacksonJson = objectMapper.writeValueAsString(testData);

long end = System.currentTimeMillis();

jacksonTotal += (end - start);

}

log.info("Jackson 序列化平均耗时: {} ms", jacksonTotal / iterations);

return jsonResult;

}

/**

* 批量解析测试

*/

private static void batchParseTest(String jsonString) throws Exception {

// Hutool

long hutoolTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

List result = JSONUtil.toList(JSONUtil.parseArray(jsonString), Variable.class);

long end = System.currentTimeMillis();

hutoolTotal += (end - start);

}

log.info("HuTool 批量解析平均耗时: {} ms", hutoolTotal / iterations);

// Fastjson2

long fastjsonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

List result = JSON.parseArray(jsonString, Variable.class);

long end = System.currentTimeMillis();

fastjsonTotal += (end - start);

}

log.info("Fastjson2 批量解析平均耗时: {} ms", fastjsonTotal / iterations);

// Gson

Gson gson = new Gson();

long gsonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

List result = gson.fromJson(jsonString, new TypeToken>() {}.getType());

long end = System.currentTimeMillis();

gsonTotal += (end - start);

}

log.info("Gson 批量解析平均耗时: {} ms", gsonTotal / iterations);

// Jackson

ObjectMapper objectMapper = new ObjectMapper();

long jacksonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

List result = objectMapper.readValue(jsonString, new TypeReference>() {});

long end = System.currentTimeMillis();

jacksonTotal += (end - start);

}

log.info("Jackson 批量解析平均耗时: {} ms", jacksonTotal / iterations);

}

/**

* 单条解析测试

*/

private static void singleParseTest(String jsonString) throws Exception {

List messageList = JSON.parseArray(jsonString, Variable.class).stream()

.map(JSON::toJSONString)

.collect(Collectors.toList());

// Hutool

long hutoolTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = JSONUtil.toBean(msg, Variable.class);

}

long end = System.currentTimeMillis();

hutoolTotal += (end - start);

}

log.info("HuTool 单条解析平均耗时: {} ms", hutoolTotal / iterations);

// Fastjson2

long fastjsonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = JSON.parseObject(msg, Variable.class);

}

long end = System.currentTimeMillis();

fastjsonTotal += (end - start);

}

log.info("Fastjson2 单条解析平均耗时: {} ms", fastjsonTotal / iterations);

// Gson

Gson gson = new Gson();

long gsonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = gson.fromJson(msg, Variable.class);

}

long end = System.currentTimeMillis();

gsonTotal += (end - start);

}

log.info("Gson 单条解析平均耗时: {} ms", gsonTotal / iterations);

// Jackson

ObjectMapper objectMapper = new ObjectMapper();

long jacksonTotal = 0;

for (int i = 0; i < iterations; i++) {

long start = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = objectMapper.readValue(msg, Variable.class);

}

long end = System.currentTimeMillis();

jacksonTotal += (end - start);

}

log.info("Jackson 单条解析平均耗时: {} ms", jacksonTotal / iterations);

}

/**

* 循环遍历单条解析并插入集合测试

*/

/**

* 循环遍历单条解析并插入集合测试 (平均耗时计算)

*/

static void singleParseAndAddListTest(String jsonString) throws Exception {

// 转换为模拟 MQ 消息体

List messageList = JSON.parseArray(jsonString, Variable.class).stream()

.map(JSON::toJSONString) // 将每个对象转为 JSON 字符串模拟单条消息

.collect(Collectors.toList());

// 平均耗时变量定义

double hutoolTotalTime = 0;

double fastjsonTotalTime = 0;

double gsonTotalTime = 0;

double jacksonTotalTime = 0;

// 循环 10 次计算平均耗时

for (int i = 0; i < iterations; i++) {

// 1. Hutool JSONUtil 单条解析

List hutoolList = new ArrayList<>();

long hutoolStart = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = JSONUtil.toBean(msg, Variable.class);

hutoolList.add(v); // 将对象存入集合

}

long hutoolEnd = System.currentTimeMillis();

hutoolTotalTime += (hutoolEnd - hutoolStart);

// 2. Fastjson2 单条解析

List fastjsonList = new ArrayList<>();

long fastjsonStart = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = JSON.parseObject(msg, Variable.class);

fastjsonList.add(v);

}

long fastjsonEnd = System.currentTimeMillis();

fastjsonTotalTime += (fastjsonEnd - fastjsonStart);

// 3. Gson 单条解析

List gsonList = new ArrayList<>();

Gson gson = new Gson();

long gsonStart = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = gson.fromJson(msg, Variable.class);

gsonList.add(v);

}

long gsonEnd = System.currentTimeMillis();

gsonTotalTime += (gsonEnd - gsonStart);

// 4. Jackson 单条解析

List jacksonList = new ArrayList<>();

ObjectMapper objectMapper = new ObjectMapper();

long jacksonStart = System.currentTimeMillis();

for (String msg : messageList) {

Variable v = objectMapper.readValue(msg, Variable.class);

jacksonList.add(v);

}

long jacksonEnd = System.currentTimeMillis();

jacksonTotalTime += (jacksonEnd - jacksonStart);

}

// 输出平均耗时结果

log.info("HuTool 单条解析并存入集合平均耗时: {} ms", hutoolTotalTime / iterations);

log.info("Fastjson2 单条解析并存入集合平均耗时: {} ms", fastjsonTotalTime / iterations);

log.info("Gson 单条解析并存入集合平均耗时: {} ms", gsonTotalTime / iterations);

log.info("Jackson 单条解析并存入集合平均耗时: {} ms", jacksonTotalTime / iterations);

}

}

4. 20W条数据、31098673字节测试结果分析(仅供参考 仅供参考 仅供参考 !!!)

库名称序列化+反序列化总耗时性能排名Fastjson2110ms左右🥇 第一名Jackson170ms左右🥈 第二名Gson210ms左右🥉 第三名Hutool1800ms左右第四名

5. 性能分析与总结

测试结果分析

Fastjson2

性能表现: 测试结果中,无论是批量解析、逐条解析还是逐条解析并插入集合,它的速度都是最快的(30ms、39ms、39.8ms)。特性优势: 支持复杂对象结构解析,API 设计简洁高效,并修复了旧版 Fastjson 的反序列化漏洞,安全性更高。适用场景: 高并发、大数据量处理及性能敏感型应用场景。

Hutool

性能表现: 表现最慢,尤其在批量解析(637ms)和逐条解析(589ms)中远落后于其他库。特性优势: API 优雅轻便,开发效率高,但性能瓶颈明显,不适合超大规模数据解析。适用场景: 适合中小规模项目的快速开发,便捷性优先于性能要求的场合。

Jackson

性能表现: 表现较优,解析速度仅次于 Fastjson2(78ms、101ms、99.8ms),兼顾性能与功能复杂性。特性优势: 支持复杂 Java 对象和自定义配置,兼容性强,适合复杂数据结构映射需求。适用场景: 企业级应用、大型复杂系统开发及对灵活性要求高的项目。

Gson

性能表现: 性能优于 Hutool,但低于 Fastjson2 和 Jackson(93ms、119ms、119.5ms)。特性优势: API 简单直观,开发成本低,但在大数据量或高并发处理时性能表现不够理想。适用场景: 小规模数据解析需求,或对性能要求不高的任务。6. 推荐选择

需求类型推荐库适用场景描述性能优先Fastjson2在所有测试场景中速度最快,适合高性能和高并发场景,适合日志分析、大数据处理和消息队列数据解析等应用。轻量便捷Hutool更适合中小规模项目的快速开发,虽然性能较低,但 API 优雅轻便,适合便捷性优先的场合。功能复杂需求Jackson兼顾性能与灵活性,支持复杂数据结构和自定义配置,适合大型企业级应用或复杂对象映射需求。简单解析需求GsonAPI 简洁易用,适合小规模数据解析任务,学习成本低,但不适合大数据和高并发需求。7. 结论与建议

Fastjson2:

性能最高,适合高并发与大数据处理需求。安全性较高,是性能敏感应用的首选。

Hutool:

开发便捷但性能较低,适合中小规模项目。如果对开发效率要求高且数据量适中,可以选择它。

Jackson:

性能与灵活性兼顾,适合复杂对象和企业级系统。面向需要自定义解析规则的场景表现更出色。

Gson:

简单易用但性能低于 Fastjson2 和 Jackson。适合小型项目或对性能要求不高的场合。注意事项

安全性: Fastjson2 安全性最佳,其他库需关注版本更新,以避免反序列化漏洞。兼容性: Jackson 在跨平台兼容性和复杂结构处理方面表现更佳。性能评估: 项目正式使用前,应基于实际生产环境进行更大规模的性能测试和压力测试。仅当前测试数据明确显示:

Fastjson2 性能最佳,适合高性能需求。Hutool 性能最慢,更适合便捷开发而非大规模数据解析。Jackson 在性能和灵活性之间取得平衡,适合复杂应用场景。Gson 表现优于 Hutool,但略逊于 Fastjson2 和 Jackson,适合轻量级需求。

相关推荐

服务器登录密码如何修改
beat365中国官方网站

服务器登录密码如何修改

📅 08-28 👁️ 2181
使用命令提示符绕过 Windows 10密码的3种简单方法 - 都叫兽软件
macos:查看文件的完整路径(12.7)
365亚洲体育投注

macos:查看文件的完整路径(12.7)

📅 09-15 👁️ 8416