50 个版本 (15 个破坏性更新)
使用旧的 Rust 2015
0.16.0 | 2017 年 9 月 10 日 |
---|---|
0.13.0 | 2017 年 9 月 8 日 |
0.0.4 | 2017 年 7 月 24 日 |
#1988 在 解析器实现
83 每月下载量
190KB
6K SLoC
皮克勒
直接拾取值而不进行标记化的 Rust JSON 解析器
摘要
皮克勒是一个直接拾取值而不进行标记化的 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.14.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
文档
限制
贡献
欢迎任何形式的贡献(例如评论、建议、问题、错误报告和pull request)。
依赖
约570KB
约11K SLoC