写点什么

Fastjon2 他来了,性能显著提升,还能再战十年

作者:共饮一杯无
  • 2022-11-28
    浙江
  • 本文字数:4002 字

    阅读完需:约 13 分钟

Fastjon2他来了,性能显著提升,还能再战十年

概述

阿里官方给的定义是,FASTJSON 是阿里巴巴的开源 JSON 解析库,它可以解析 JSON 格式的字符串,支持将 Java Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean。FASTJSON 相对其他 JSON 库的特点是快,从 2011 年 fastjson 发布 1.1.x 版本之后,其性能从未被其他 Java 实现的 JSON 库超越。FASTJSON 2.0 是 FASTJSON 项目的重要升级,目标是为下一个十年提供一个高性能的 JSON 库,同一套 API 支持 JSON/JSONB 两种协议,JSONPath 是一等公民,支持全量解析和部分解析,支持 Java 服务端、客户端 Android、大数据场景。

使用

引入 Maven 依赖

FASTJSON 2.0 中,groupId 和 1.x 不一样,是 com.alibaba.fastjson2


<dependency>  <groupId>com.alibaba.fastjson2</groupId>  <artifactId>fastjson2</artifactId>  <version>2.0.1</version></dependency>
复制代码


https://repo1.maven.org/maven2/com/alibaba/fastjson2/fastjson2/2.0 之前的 FASTJSON 坐标如下,最新版本为 1.2.79:


<dependency>     <groupId>com.alibaba</groupId>     <artifactId>fastjson</artifactId>     <version> 1.2.79</version></dependency>
复制代码


https://github.com/alibaba/fastjson/releases💡官方说明:如果原来使用 fastjson 1.2.x 版本,可以使用兼容包,兼容包不能保证 100%兼容,请仔细测试验证,发现问题请及时反馈。兼容包坐标如下:


<dependency>  <groupId>com.alibaba</groupId>  <artifactId>fastjson</artifactId>  <version>2.0.1</version></dependency>
复制代码

常用类和方法

在 fastjson 2.0 中,package 和 1.x 不一样,是 com.alibaba.fastjson2。如果你之前用的是 fastjson1,大多数情况直接更包名就即可。


package com.alibaba.fastjson2;
class JSON { // 将字符串解析成JSONObject static JSONObject parseObject(String str); // 将字符串解析成JSONArray static JSONArray parseArray(String str); // 将字符串解析成Java对象 static T parseObject(byte[] utf8Bytes, Class<T> objectClass);
// 将Java对象输出成字符串 static String toJSONString(Object object); // 将Java对象输出成UT8编码的byte[] static byte[] toJSONBytes(Object object);}
class JSONB { // 将jsonb格式的byte[]解析成Java对象 static T parseObject(byte[] jsonbBytes, Class<T> objectClass); // 将Java对象输出成jsonb格式的byte[] static byte[] toBytes(Object object);}
class JSONObject { Object get(String key); int getIntValue(String key); Integer getInteger(String key); long getLongValue(String key); Long getLong(String key); T getObject(String key, Class<T> objectClass); // 将JSONObject对象转换为Java对象 T toJavaObject(Class<T> objectClass);}
class JSONArray { Object get(int index); int getIntValue(int index); Integer getInteger(int index); long getLongValue(int index); Long getLong(int index); T getObject(int index, Class<T> objectClass);}
class JSONPath { // 构造JSONPath static JSONPath of(String path);
// 根据path直接解析输入,会部分解析优化,不会全部解析 Object extract(JSONReader jsonReader); // 根据path对对象求值 Object eval(Object rootObject);}
class JSONReader { // 构造基于String输入的JSONReader static JSONReader of(String str); // 构造基于ut8编码byte数组输入的JSONReader static JSONReader of(byte[] utf8Bytes); // 构造基于char[]输入的JSONReader static JSONReader of(char[] chars); // 构造基于json格式byte数组输入的JSONReader static JSONReader ofJSONB(byte[] jsonbBytes)}
复制代码

常用案例

字符串转 JSON 对象/JSON 数组

对象:


String jsonObjectStr = "{\"id\":\"1\",\"name\":\"张三\"}";JSONObject jsonObject = JSON.parseObject(jsonObjectStr);int id = jsonObject.getIntValue("id");String name = jsonObject.getString("name");
复制代码


数组对象:


 //普通数组String str = "[\"id\", 123]";JSONArray jsonArray1 = JSON.parseArray(str);String key = jsonArray1.getString(0);int value = jsonArray1.getIntValue(1);log.info(key+":"+value);
//数组对象String jsonArrayObjectStr = "[{\"id\":\"1\",\"name\":\"张三\"},{\"id\":\"2\",\"name\":\"李四\"}]";JSONArray jsonArray = JSON.parseArray(jsonArrayObjectStr);JSONObject jsonObject = jsonArray.getJSONObject(1);int id = jsonObject.getIntValue("id");String name = jsonObject.getString("name");log.info(id+" "+name);
复制代码

JavaBean 对象转 JSON 格式的字符串

User user = new User();user.setId(1);user.setName("小詹");String userStr = JSON.toJSONString(user);log.info(userStr);
//JSONWriter.Feature.BeanToArray是fastjson2新特性,fastjson1中没有String toJSONString = JSON.toJSONString(user, JSONWriter.Feature.BeanToArray);log.info(toJSONString);
//JavaBean对象生成UTF8编码的byte[]byte[] utf8JSONBytes = JSON.toJSONBytes(user);log.info(new String(utf8JSONBytes));
@Dataclass User{ private int id; private String name;}
复制代码


输出如下:


INFO com.zjq.dailyrecord.utils.fastjson.Fastjson2 - {"id":1,"name":"小詹"}INFO com.zjq.dailyrecord.utils.fastjson.Fastjson2 - [1,"小詹"]INFO com.zjq.dailyrecord.utils.fastjson.Fastjson2 - {"id":1,"name":"小詹"}
复制代码

JSON 格式的字符串转 JavaBean 对象

String jsonObjectStr = "{\"id\":\"1\",\"name\":\"张三\"}";User user = JSON.parseObject(jsonObjectStr, User.class);log.info(user.toString());
复制代码


输出如下:


INFO com.zjq.dailyrecord.utils.fastjson.Fastjson2 - Fastjson2.User(id=1, name=张三)
复制代码

JSON 格式的字符串转 JavaBean 对象数组

String jsonObjectStr = "[{\"id\":\"1\",\"name\":\"小詹\"},{\"id\":\"2\",\"name\":\"zjq\"}]";List<User> userList = JSON.parseArray(jsonObjectStr, User.class);log.info(userList.toString());
复制代码


输出如下:


INFO com.zjq.dailyrecord.utils.fastjson.Fastjson2 - [Fastjson2.User(id=1, name=小詹), Fastjson2.User(id=2, name=zjq)]
复制代码

Fastjson2 相对 fastjson1 性能提升

比较版本

  • Fastjson 2.0.1

  • Fastjson 1.2.79

  • Jackson 2.12.4

Parse 性能比较

测试代码

package com.alibaba.fastjson_perf.eishay;
import org.openjdk.jmh.annotations.Mode;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.util.concurrent.TimeUnit;
public class EishayParse { public static void main(String[] args) throws RunnerException { Options options = new OptionsBuilder() .include(EishayParse.class.getName()) .mode(Mode.Throughput) .timeUnit(TimeUnit.MILLISECONDS) .forks(1) .build(); new Runner(options).run(); }}
复制代码

场景介绍及结论

  • EishayParseTreeString 场景,将 String 解析成 JSONObject/JSONArray 或者 HashMap/ArrayList。在这个场景,fastjson2 表现出了两倍于 fastjson1 的性能

  • EishayParseString 场景,将 String 反序列化为 JavaBean 对象,在这个场景 fastjson2 相对于 fastjson1 性能提升了 30%的性能。

  • EishayParseStringPretty,将格式化带空格和换行符缩进的 String 反序列化为 JavaBean 对象,fastjson2 在 3.44 倍于 fastjson1。这个场景在 fastjson1 中是弱项,在 fastjson2 中采用新解析的算法,性能有了非常大提升。

  • EishayParseUTF8Bytes,将 UTF8 格式的 byte[]反序列化为 JavaBean 对象。

WriteString

测试代码

package com.alibaba.fastjson_perf.eishay;
import org.openjdk.jmh.annotations.Mode;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.util.concurrent.TimeUnit;
public class EishayWrite { public static void main(String[] args) throws RunnerException { Options options = new OptionsBuilder() .include(EishayWrite.class.getName()) .mode(Mode.Throughput) .timeUnit(TimeUnit.MILLISECONDS) .forks(1) .build(); new Runner(options).run(); }}
复制代码

场景介绍及结论

  • EishayWriteString 场景,将 JavaBean 对象序列化为字符串。这个场景中,fastjson2 比 fastjson1 和 jackson 分别有 164%和 85%的性能提升

  • EishayWriteUTF8Bytes 场景,将 JavaBean 对象序列化为 UTF8 格式的 byte 数组。这个场景中,fastjson2 比 fastjson1 和 jackson 分别有 185%和 93%的性能提升


来源

https://github.com/alibaba/fastjson/releases

https://github.com/alibaba/fastjson2/releases/tag/2.0.1

https://github.com/alibaba/fastjson2/wiki/fastjson_benchmark


本文内容到此结束了,

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

主页共饮一杯无的博客汇总👨‍💻

保持热爱,奔赴下一场山海。🏃🏃🏃

发布于: 刚刚阅读数: 4
用户头像

鲜衣怒马意气风发,愿你归来仍是少年。 2018-10-19 加入

全栈开发者,CSDN博客专家,51CTO 专家博主,阿里云专家博主,华为云享专家,持续输出干货,欢迎关注。

评论

发布
暂无评论
Fastjon2他来了,性能显著提升,还能再战十年_Java_共饮一杯无_InfoQ写作社区