5 个版本
0.2.3 | 2021 年 5 月 20 日 |
---|---|
0.2.2 | 2021 年 5 月 2 日 |
0.2.1 | 2021 年 4 月 29 日 |
0.2.0 | 2021 年 4 月 28 日 |
0.1.0 | 2021 年 2 月 3 日 |
#2830 在 解析器实现 中
45 每月下载量
在 3 crate 中使用
120KB
3.5K SLoC
Messy Json
Rust 动态结构文档 JSON 解析器
简介
Rust 生态系统允许在编译时很好地实现 JSON 反序列化到 Rust 结构,但是当涉及到动态结构对象的运行时反序列化时,情况就变得有些稀疏。这个 crate 以一种简单的方式解决这个问题,类似于 serde_json
's Value
。
示例
use messy_json::*;
use serde::de::DeserializeSeed;
let nested_string = MessyJson::from(MessyJsonInner::String(MessyJsonScalar::new(false)));
let schema: MessyJson = MessyJson::from(MessyJsonInner::Obj(MessyJsonObject::from(MessyJsonObjectInner::new(
vec![(arcstr::literal!("hello"), nested_string)]
.into_iter()
.collect(),
false,
))));
let value = r#"
{
"hello": "world"
}
"#;
let mut deserializer = serde_json::Deserializer::from_str(value);
let parsed: MessyJsonValueContainer = schema.builder(MessyJsonSettings::default()).deserialize(&mut deserializer).unwrap();
println!("{:#?}", parsed)
性能
当所有字段都是必需的时,这个 crate 比使用 serde_json
's Value
更有效。当一些字段是可选时,性能与 serde_json
's Value
相当。
然而,这个 crate 在使用 serde 的 proc-macro
进行反序列化(这根本不是动态结构)方面落后很多。
当将 Allocator
特性合并到 stable
时,可以使用自定义的基于区域的分配器(如 Bumpalo)来填补这个差距。
这个 crate 实现了基准测试。以下图表是在具有以下配置的机器上运行的
- CPU:Intel i9-9900K @ 4.7Ghz
- 内存:32 Gb RAM @ 2133 Mhz
- 内核:
5.11.16-arch1-1
- Rust:
rustc 1.51.0 (2fd73fabe 2021-03-23)
在以下基准测试中,与 serde_json
's Value
和使用 serde's
derive
生成的宏解析器进行了比较。
虚拟对象
以下基准测试包括反序列化 JSON 文档
{
"hello":
{
"hola": "world"
}
}
接受的模式应如下所示
use std::borrow::Cow;
struct DummyObjNested<'a> {
hola: Cow<'a, str>,
}
struct DummyObj<'a> {
hello: DummyObjNested<'a>,
}
结果显示,messy_json
比宏生成的反序列化器慢,但比使用serde_json
's Value
快。
部分对象
以下基准测试包括反序列化 JSON 文档
{
"hello":
{
"hola": "world"
}
}
接受的模式应如下所示
use serde::{Serialize, Deserialize};
use std::borrow::Cow;
#[derive(Serialize, Deserialize)]
struct PartialObjNested<'a> {
hola: Cow<'a, str>,
}
#[derive(Serialize, Deserialize)]
struct PartialObj<'a> {
hello: PartialObjNested<'a>,
coucou: Option<Cow<'a, str>>,
coucou1: Option<Cow<'a, str>>,
coucou2: Option<Cow<'a, str>>,
}
结果显示,messy_json
比宏生成的反序列化器慢,并且与serde_json
's Value
相当。当使用可选值时,该包必须检查每个对象是否满足所有必需的值,因此性能下降。在未来,当Rust语言的alloc_api
合并到stable
时,可以实施优化,以减少检查缺失字段所需的时间。
简单对象
以下基准测试包括反序列化 JSON 文档
{
"hello": "world"
}
接受的模式应如下所示
use std::borrow::Cow;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct SimpleObj<'a> {
hello: Cow<'a, str>,
}
结果显示,messy_json
比宏生成的反序列化器慢,但仍然比serde_json
's Value
快。
依赖关系
~0.8–1.5MB
~29K SLoC