写点什么

高性能 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:073970

评论

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

2023年了 对Go做一个全网最全的总结

卡二条

Go Go Concurrency Patterns Go web

您有一套专属权益已送达,请注意查收

天翼云开发者社区

2023-01-11:体育馆的人流量。编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。返回按 visit_date 升序排列 的结果表。 DROP TAB

福大大架构师每日一题

MySQL 福大大

天翼云荣获2022年度“边缘计算先锋企业”“分布式云先锋企业”称号!

天翼云开发者社区

阿里巴巴重磅开源云原生网关: Higress

阿里巴巴中间件

阿里云 云原生 Higress

RatingBar(星级评分条)

芯动大师

Android Studio 星级评分条 ratingbar

应用 Serverless 化,让业务开发心无旁骛

阿里巴巴中间件

阿里云 Serverless 云原生

事件总线 + 函数计算构建云上最佳事件驱动架构应用

Serverless Devs

如何选择数据可视化图表?

搞大屏的小北

大前端—2022明星项目,2023展望

非喵鱼

JavaScript Vue 前端 React 前沿技术

容器服务与达摩院合作 AHPA 获 AAAI 2023 IAAI人工智能创新应用奖

阿里巴巴中间件

阿里云 容器 云原生

项目制实践如何助力组织进化

feijieppm

项目管理 研发效能 技术管理 文化 & 方法 效能度量

DW-Siam:Deeper and Wider Siamese Networks for Real-Time Visual Tracking 更宽更深的孪生网络

Geek_7ubdnf

神经网络

场景 | 九科信息大型制造企业RPA数字化解决方案

九科Ninetech

再谈持续测试

FunTester

大规模 Kubernetes 集群故障注入的利器-ChaosBlade

阿里巴巴中间件

阿里云 Kubernetes 云原生 ChaosBlade

《天翼云安全白皮书》发布!共铸国云安全生态!

天翼云开发者社区

安全可信| 密评合规!天翼云全栈混合云通过商用密码应用安全性评估!

天翼云开发者社区

TapTap算法平台的 Serverless 探索之路

Serverless Devs

DataEase 在 Windows 系统下的 jar 包部署

搞大屏的小北

亚马逊云科技 2022 re:Invent 观察 | 天下武功,唯快不破

亚马逊云科技 (Amazon Web Services)

亚马逊云科技 Builder 专栏

「认知」打工人的自我修养

职场 认知

什么是云渲染?云渲染速度快吗?

Renderbus瑞云渲染农场

云渲染 云渲染是什么 云渲染速度快吗

2023年有哪些具备潜力的加密投资标的?

股市老人

微服务引擎 MSE 升级至 3.0:降低微服务在云原生时代的演进成本

阿里巴巴中间件

阿里云 微服务 云原生

效能改进中的度量实践

feijieppm

项目管理 研发效能 技术管理 文化 & 方法 效能度量

Higress 开源后,我们整理了开发者最关心的 15 个问题

阿里巴巴中间件

阿里云 云原生 Higress

DataEase 在 Mac 系统下的 jar 包部署

搞大屏的小北

DataEase Mac 系统 jar 包部署

DataEase 本地源码启动

搞大屏的小北

效能指标「研发浓度」在项目度量中的应用

feijieppm

项目管理 技术管理 文化 & 方法 效能度量 #研发效能

问题盘点|使用 Prometheus 监控 Kafka,我们该关注哪些指标

阿里巴巴中间件

kafka 阿里云 云原生 Prometheus

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