1 个不稳定版本
使用旧的Rust 2015
0.16.1 | 2021年2月19日 |
---|
#2499 in 解析实现
150KB
3.5K SLoC
Pikkr
在Rust中直接提取值而不进行标记化操作的JSON解析器
摘要
Pikkr是一个在Rust中直接提取值而不进行标记化操作的JSON解析器。这个JSON解析器是基于Y. Li, N. R. Katsipoulakis, B. Chandramouli, J. Goldstein, and D. Kossmann. Mison: a fast JSON parser for data analytics. In VLDB, 2017。
这个JSON解析器在不需要使用有限状态机(FSM)和进行标记化操作的情况下从JSON记录中提取值。它按照以下步骤解析JSON记录
- [索引] 使用SIMD指令和位操作创建索引,该索引将查询字段的逻辑位置映射到它们的物理位置。
- [基本解析] 通过使用在前面过程中创建的索引扫描JSON记录以找到查询字段的值,并在早期阶段学习它们的逻辑位置(即JSON结构的模式)。
- [推测解析] 使用学习到的结果信息推测查询字段的逻辑位置,在后期阶段直接跳转到它们的物理位置并提取值。如果推测失败,则回退到基本解析。
当在JSON数据流或JSON集合中存在有限数量的不同JSON结构变体时,这个JSON解析器表现良好,这在数据分析领域是一个常见的情况。
请阅读开头段落中提到的论文,以了解JSON解析算法的详细信息。
性能
基准测试结果
硬件
Model Name: MacBook Pro
Processor Name: Intel Core i7
Processor Speed: 3.3 GHz
Number of Processors: 1
Total Number of Cores: 2
L2 Cache (per Core): 256 KB
L3 Cache: 4 MB
Memory: 16 GB
Rust
$ cargo --version
cargo 0.23.0-nightly (34c0674a2 2017-09-01)
$ rustc --version
rustc 1.22.0-nightly (d93036a04 2017-09-07)
Crates
- serde_json 1.0.3
- json 0.11.9
- pikkr 0.16.0
JSON数据
- "关于创业公司信息的JSON数据集"来自JSON数据集 | JSON Studio。
基准测试代码
示例
代码
extern crate pikkr;
fn main() {
let queries = vec![
"$.f1".as_bytes(),
"$.f2.f1".as_bytes(),
];
let train_num = 2; // Number of records used as training data
// before Pikkr starts speculative parsing.
let mut p = match pikkr::Pikkr::new(&queries, train_num) {
Ok(p) => p,
Err(err) => panic!("There was a problem creating a JSON parser: {:?}", err.kind()),
};
let recs = vec![
r#"{"f1": "a", "f2": {"f1": 1, "f2": true}}"#,
r#"{"f1": "b", "f2": {"f1": 2, "f2": true}}"#,
r#"{"f1": "c", "f2": {"f1": 3, "f2": true}}"#, // Speculative parsing starts from this record.
r#"{"f2": {"f2": true, "f1": 4}, "f1": "d"}"#,
r#"{"f2": {"f2": true, "f1": 5}}"#,
r#"{"f1": "e"}"#
];
for rec in recs {
match p.parse(rec.as_bytes()) {
Ok(results) => {
for result in results {
print!("{} ", match result {
Some(result) => String::from_utf8(result.to_vec()).unwrap(),
None => String::from("None"),
});
}
println!();
},
Err(err) => println!("There was a problem parsing a record: {:?}", err.kind()),
}
}
/*
Output:
"a" 1
"b" 2
"c" 3
"d" 4
None 5
"e" None
*/
}
构建
$ cargo --version
cargo 0.23.0-nightly (34c0674a2 2017-09-01) # Make sure that nightly release is being used.
$ RUSTFLAGS="-C target-cpu=native" cargo build --release
运行
$ ./target/release/[package name]
"a" 1
"b" 2
"c" 3
"d" 4
None 5
"e" None
文档
限制
- 需要使用Rust 夜间频道和支持AVX2指令的CPU来构建依赖Pikkr的Rust源代码并运行可执行二进制文件,因为Pikkr使用了AVX2指令。
贡献
欢迎任何形式的贡献(例如评论、建议、问题、错误报告和拉取请求)。