AICon 北京站 Keynote 亮点揭秘,想了解 Agent 智能体来就对了! 了解详情
写点什么

高性能 Rust JSON 库 sonic-rs 优化实践

  • 2024-03-26
    北京
  • 本文字数:2008 字

    阅读完需:约 7 分钟

大小:904.33K时长:05:08
高性能 Rust JSON 库 sonic-rs优化实践

一、sonic-rs 介绍

sonic-rs 是一个基于 SIMD 的高性能 Rust JSON 库,是 sonic JSON 库的 Rust 版本。


字节跳动 sonic 开源项目如今包含了不同语言的多个 JSON 库(如下)。其中,sonic-go 最先开源,使用了 JIT 和 SIMD 技术,sonic-cpp 使用了 C++ 模板和 SIMD 技术,这两个 JSON 库均已经在字节内部得到了较大规模的落地。在成本优化大背景下,为了帮助 Golang 业务迁移 Rust,优化 Rust JSON 性能,我们基于 JSON 方面的优化经验和实践,用纯 Rust 语言开发了高性能的 JSON 库  sonic-rs。


  • sonic(Golang JSON 库):https://github.com/bytedance/sonic

  • sonic-cpp(C++ JSON 库):https://github.com/bytedance/sonic-cpp

  • sonic-rs(Rust JSON 库):https://github.com/cloudwego/sonic-rs


sonic-rs 目前支持的 JSON 功能比较齐全,基本对齐了 serde-json 的相关功能,并且提供更加丰富的功能和更多的高性能接口。sonic-rs 的主要功能特点有:


  • 基本兼容 Serde 生态,同时支持 Volo 中的 FastStr 类型

  • 支持动态类型编解码和按需解析

  • 支持 LazyVaue,RawNumber 等类型

  • 支持 UTF-8 校验和标准浮点数精度


在性能方面,我们基于 serde-rs 官方 benchmark (https://github.com/serde-rs/json-benchmark) 提供的 Rust 结构体和 JSON 数据,对 serde-json, simd-json 和 sonic-rs 在 Rust 结构体下的解析性能进行了测试,可以发现 sonic-rs 的性能是 simd-json 的 1.5~2 倍,是 serde-json 2 倍:


二、sonic-rs 优化实践


sonic-rs 的优化主要基于 SIMD,其中部分借鉴了其他 JSON 库,如 simd-json 的优化思路。SIMD (Single instruction, multiple data) 是一种并行优化技术,可以用一条指令,并行处理多个数据。如今大多数 CPU 已经支持了各种 SIMD 指令集。例如,x86_64 架构下的 SSE,AVX2,AVX512, aarch64 架构下的 neon 指令集等。使用 SIMD 指令优化之后,对于合适的任务,程序执行的指令数量会更少,因此性能会更好。


在整体设计上,sonic-rs 并没有采用 simd-json 那种二阶段解析的思路,主要将 SIMD 优化应用于 JSON 解析和序列化中的热点,包括字符串序列化、按需解析和浮点数解析等。

1. SIMD 优化字符串序列化


字符串序列化是 JSON 序列化的热点。序列化时,需要扫描字符串中的转义字符。对于较长的字符串,逐个字节判断转义字符的操作是比较耗时的,扫描转义字符非常适合使用 SIMD 来加速。


如果用 AVX2 指令来扫描转义字符,如下面代码所示。这段 SIMD 代码在 haswell 架构下面,开 O3 优化之后,其实只有六条 SIMD 指令,即 6 条 SIMD 指令可以一次性扫描 32 个字节。相比较标量代码来说,大大减少了程序指令的数量,从而减少了程序的执行时间。


2. SIMD 优化按需解析


很多业务场景只用到 JSON 中的部分字段,很适合按需解析,在解析时跳过不需要的 JSON 字段。在跳过 JSON 字段时,难点在于如何高效跳过 JSON 中的 object 和 array。


基于 JSON 中 object 和 array 括号必须匹配的语法规则,sonic-rs 使用 SIMD 实现了高效的括号匹配算法。先通过 SIMD 得到 json object 和 array 的 bitmap,然后通过计算括号的数量来跳过 object 和 array。当发现括号匹配时,就可以跳过该 object 或 array。


3. SIMD 优化浮点数解析


浮点数解析是 JSON 解析中的一个性能热点。在字节内部,我们发现 JSON 中大部分浮点数的尾数都比较长,也适合使用 SIMD 优化。如下图,对于一段长 16 个字节的浮点数尾数 "1234342112345678":


  • 先将这段字符串读取到向量寄存器里面,此时向量的每个数字还是 ASCII 码的值。

  • 其次,用向量的减法,逐个字节减去 ASCII 码 '0' 得到 v1。这时。v1 里面的数字已经是十进制。

  • 然后,继续对 v1 里面的各个数字用向量指令做两两乘加(高位乘以 10 再加上低位),得到 v2。v2 里面的各个数已经是十进制的两位数。

  • 以此类推,利用 SIMD 指令逐层累加,最终就得到 v16。v16 里面是一个 16 位数,即最终的尾数解析结果。

  • 最后,我们再用向量指令把 v16 转成 u64 类型。


整个解析过程,不用遍历浮点数尾数的每一个字符,就能完成浮点数尾数解析。


三、sonic-rs 现状和规划


sonic-rs 已经开源几个月了,目前迭代到了 0.3 版本,已经支持 Rust stable 版本,并且支持了 aarch64 架构。sonic-rs 沉淀了一些使用文档,用以帮助各方面的开发者:


  • Golang 迁移 Rust 用户使用 sonic-rs:https://github.com/cloudwego/sonic-rs/blob/main/docs/for_Golang_user_zh.md

  • Rust serde-json 用户迁移 sonic-rs:https://github.com/cloudwego/sonic-rs/blob/main/docs/serdejson_compatibility.md

  • 性能优化细节:https://github.com/cloudwego/sonic-rs/blob/main/docs/performance_zh.md


后续,sonic-rs 会在性能,易用性和稳定性上面继续打磨,预期会支持对 Bytes/FastStr 等常见数据类型的零拷贝解析,支持运动时检测 SIMD 指令等,欢迎感兴趣的开发者一起加入我们。


项目地址

GitHub:https://github.com/cloudwego

官网:www.cloudwego.io

2024-03-26 17:074183

评论

发布
暂无评论
发现更多内容

耗时三年开源的H5商城,强烈推荐

越长大越悲伤

Java 开源 springboot

多邻国还是流利说

escray

技术人写作 21 天技术人写作行动营 21 天

ERP和MES的区别与联系,这篇接地气的文章终于讲明白了!

优秀

MES系统 mes ERP系统 mes和erp区别

“敏捷教练进阶课程”2024年1月27-28日 · A-CSM认证在线周末班【分时段模块化教学】CST导师亲授

ShineScrum

敏捷教练

Amazon WorkSpaces 推出 Amazon WorkSpaces Web

亚马逊云科技 (Amazon Web Services)

容器 Amazon WorkSpaces

🎉开发者的福音:TinyVue 组件库文档大优化!类型更详细,描述更清晰!

Kagol

开源 Vue 前端 UI组件库

英特尔李映:开源开放是软件生态开拓进取的原动力

E科讯

【EMNLP 2023】面向Stable Diffusion的自动Prompt工程算法BeautifulPrompt

阿里云大数据AI技术

Groovy StringBuilder类踩坑

FunTester

wing一款轻量快捷的团队开发工具

iofomo

Python 跨平台 开发工具

Native Drawing开发指导,实现HarmonyOS基本图形和字体的绘制

HarmonyOS开发者

HarmonyOS

一文让你知道企业真正需要一个怎样的远程协同运维平台?

行云管家

运维 远程运维 远程协同

面试问题总结(一)

xfgg

Java

从ByteHouse网关,看如何进一步提升OLAP引擎性能

字节跳动数据平台

数据库 大数据 云原生 数仓 企业号12月PK榜

2023 Flink Forward Asia 参会指南来啦!

Apache Flink

大数据 flink

Amazon WorkSpaces 现在提供使用 WorkSpaces 流协议(WSP)的 Web Access

亚马逊云科技 (Amazon Web Services)

Amazon WorkSpaces

GPU在元宇宙中的作用—元宇宙云端解决方案

3DCAT实时渲染

元宇宙 实时渲染

我的2023年度关键词:迎接不一样的挑战,充实自我

芯动大师

#技术人的2023总结

使用 Kubernetes Agent Server 实现 GitOps

极狐GitLab

Kubernetes DevOps gitlab gitops workflow

14 | 排序优化:如何实现一个通用的、高性能的排序函数.md

鲁米

服务器异常问题排查指南

AiDaddy

trouble shooting 线上问题排查 服务器异常排查 linux 命令

写作训练营打卡1--最喜欢的极客时间作者

Avril

[译]你需要知道的CSS属性isolation

南城FE

CSS 前端 布局

喜报!MIAOYUN入选成都高新区“瞪羚企业”

MIAOYUN

云计算 MIAOYUN 瞪羚企业 成都高新梯度培育企业 企业资质

「智造」第12期:浅谈时序数据库的应用及发展

用友BIP

时序数据库

JDK1.8 ConcurrentHashMap 核心源码(面试重点)

是月月啊2023

SQL ALTER TABLE 语句- 灵活修改表结构和数据类型

小万哥

MySQL 数据库 sql 程序员 后端开发

【Android】深入Binder拦截

iofomo

android 拦截器 binder

另一种学习 Linux kernel 的方式 —— UML

袁世超

UML Linux Kenel

跨界-我今年最难的一件事

学渣汪在央企打怪升级

Wireshark中的TCP协议包分析

小齐写代码

高性能 Rust JSON 库 sonic-rs优化实践_编程语言_刘强_InfoQ精选文章