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

简介: 阿里官方给的定义是,FASTJSON是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。

概述

阿里官方给的定义是,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));

@Data
class 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性能比较

测试代码

https://github.com/alibaba/fastjson2/blob/2.0.1/core/src/test/java/com/alibaba/fastjson_perf/eishay/EishayParse.java

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

测试代码

https://github.com/alibaba/fastjson2/blob/2.0.1/core/src/test/java/com/alibaba/fastjson_perf/eishay/EishayWrite.java

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

相关文章
|
12月前
|
机器学习/深度学习 人工智能 架构师
谷歌长文总结四代TPU打造经验:里程碑式的TPUv4是怎样炼成的?
谷歌长文总结四代TPU打造经验:里程碑式的TPUv4是怎样炼成的?
271 0
|
弹性计算 运维 Kubernetes
腾讯全面上云背后:程序员的技术焦虑和技术理想
腾讯全面上云背后:程序员的技术焦虑和技术理想
215 0
|
SQL 缓存 监控
深度专访高楼:如何成为一个身价百万的性能工程师?
很多人眼里的性能,不过是开发的边角料,看待性能工程师,天然就戴着一副有色眼镜。其实,一个可以独立做性能分析的人,在市场上抢都抢不到。可是,怎么才能成为这样的性能工程师呢?InfoQ 深度采访盾山科技 CEO、7DGroup 创始人,他也是 2022 年 QCon+ 【自动化测试】专题的出品人。他将从底层为你揭秘性能高手的思维模式,以期帮助大量性能工程师们拨开职业的迷雾,登上身价百万的台阶。
204 0
深度专访高楼:如何成为一个身价百万的性能工程师?
|
人工智能 量子技术 开发者
5年计划两年完成!霍尼韦尔超速将量子计算机体量翻十倍!
近日,霍尼韦尔又搞出了「大动作」,霍尼韦尔预计将在18至24个月内提前完成「五年计划」:量子计算机体量翻十倍!
116 0
5年计划两年完成!霍尼韦尔超速将量子计算机体量翻十倍!
|
供应链 搜索推荐 大数据
王者本色再现,苏宁为何能在家电市场长期雄踞第一
王者本色再现,苏宁为何能在家电市场长期雄踞第一
122 0
王者本色再现,苏宁为何能在家电市场长期雄踞第一
|
人工智能
水滴筹的2018:飞速进化,不改初心
水滴筹的2018:飞速进化,不改初心
276 0
水滴筹的2018:飞速进化,不改初心
|
存储 人工智能 弹性计算
阿里云算力的十年更迭史,重点都在这了!
3 月 29 日,在阿里云计算峰会上,阿里云弹性计算负责人张献涛博士,作为开场嘉宾,做了《高效稳定,助力云上企业敏捷创新》的主题分享,回顾阿里云算力的十年更迭史,讲解阿里云强劲、稳定、安全的计算产品家族。
阿里云算力的十年更迭史,重点都在这了!
|
程序员
老程序员的巨大优势——积累起来的经验——打破30/35岁的魔咒!
  最近找了一份工作,在工作中体验到了以前积累的工作经验的巨大优势。     需求很简单,就是做一个网站,展示一下要出售的商品,再加上一个资讯作为陪衬。当然还要有一个会员管理,会员分类,会员购物车、订单、网银接口等,还有SEO的注意事项,再加上URL重写,还有就是业务员和会员的关系。
997 0
|
架构师 Java 程序员
从普通程序员到身价过百亿:追求长期价值的耐心,决定了你能走多远
一提到程序员,很多人脑海里马上会出现这些标签:格子衬衫、牛仔裤、代码、bug、木讷、不善言辞等等。但有一个词似乎更能概括:改变世界。 程序改变世界,已经有几十年了,但真正进入大众的生活,应该是从2007年智能手机的应用开始,越来越多的人开始关注技术和程序员。
1852 0
阿里五年,再难,也没想过要趴下
在阿里打怪升级的路上,每件事都很难。但幸好,这一路上我们这群人,再难,也没想过趴下。
1725 0