26个版本 (8个破坏性版本)
0.9.1 | 2024年4月3日 |
---|---|
0.9.0 | 2024年3月28日 |
0.8.7 | 2024年2月29日 |
0.8.4 | 2023年10月30日 |
0.1.1 | 2022年7月26日 |
#319 在 解析实现
785KB
16K SLoC
rsonpath – SIMD驱动的JSONPath 🚀
用于查询大量流式数据集的实验性JSONPath引擎。
rsonpath
库提供了一个JSONPath解析器和查询执行引擎 rq
,它利用SIMD指令提供了比传统引擎更高的吞吐量。
在Pison数据集上对 rsonpath
与一个参考无SIMD引擎的基准测试。 注意:尺度是对数!
用法
要在文件上运行JSONPath查询,执行
rq '$..a.b' ./file.json
如果省略文件,则引擎读取标准输入。也可以传递内联的JSON
$ rq '$..a.b' --json '{"c":{"a":{"b":42}}}'
42
有关详细信息,请参阅 rq --help
或 rsonbook。
结果
查询运行的结果是一系列匹配值,由换行符分隔。或者,传递 --result count
仅返回匹配数,这可能要快得多。有关其他结果模式,请参阅 --help
使用页面。
安装
请参阅 发行版 以获取所有一级支持目标机的预编译二进制文件。
cargo
最简单的安装方法是使用 cargo
。
$ cargo install rsonpath
...
本地CPU优化
如果速度是最重要的,您应该使用本地CPU指令支持安装 rsonpath
。这将产生一个二进制文件,它是 不可移植的,可能在任何其他机器上无法正常工作,但将榨取最后一点吞吐量。
为此,请运行以下 cargo install
变体
$ RUSTFLAGS="-C target-cpu=native" cargo install rsonpath
...
查看 rsonbook中的相关章节。
查询语言
该项目正在积极开发中,目前仅支持JSONPath查询语言的子集。查询是一系列段,每个段包含一个或多个选择器。
支持的段
段 | 语法 | 支持 | 自 | 跟踪问题 |
---|---|---|---|---|
子段(单个) | [<选择器>] |
✔️ | v0.1.0 | |
子段(多个) | [<选择器1>,...,<选择器N>] |
❌ | ||
后代段(单个) | ..[<选择器>] |
✔️ | v0.1.0 | |
后代段(多个) | ..[<选择器1>,...,<选择器N>] |
❌ |
支持的选择器
选择器 | 语法 | 支持 | 自 | 跟踪问题 |
---|---|---|---|---|
根 | $ |
✔️ | v0.1.0 | |
名称 | .<成员> , [<成员>] |
✔️ | v0.1.0 | |
通配符 | .* , ..* , [*] |
✔️ | v0.4.0 | |
索引(数组索引) | [<索引>] |
✔️ | v0.5.0 | |
索引(数组末尾索引) | [-<索引>] |
❌ | ||
数组切片(正向,正界限) | [<开始>:<结束>:<步长>] |
✔️ | v0.9.0 | #152 |
数组切片(正向,任意界限) | [<开始>:<结束>:<步长>] |
❌ | ||
数组切片(反向,任意界限) | [<开始>:<结束>:-<步长>] |
❌ | ||
过滤器 – 存在性测试 | [?<路径>] |
❌ | #154 | |
过滤器 – 常量原子比较 | [?<路径> <二元运算符> <原子>] |
❌ | #156 | |
过滤器 – 逻辑表达式 | && , || , ! |
❌ | ||
过滤器 – 嵌套 | [?<表达式>[?<表达式>]...] |
❌ | ||
过滤器 – 任意比较 | [?<路径> <二元运算符> <路径>] |
❌ | ||
过滤器 – 函数扩展 | [?函数(<路径>)] |
❌ |
支持的平台
该软件包为所有一级Rust目标持续构建,并且对于可以使用GitHub动作图像运行的目标持续运行测试。仅支持x86/x86_64平台上的SIMD。
目标三元组 | nosimd构建 | SIMD支持 | 持续测试 | 跟踪问题 |
---|---|---|---|---|
aarch64-unknown-linux-gnu | ✔️ | ❌ | ✔️ | #21, #115 |
i686-unknown-linux-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-unknown-linux-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-apple-darwin | ✔️ | ✔️ | ✔️ | |
i686-pc-windows-gnu | ✔️ | ✔️ | ✔️ | |
i686-pc-windows-msvc | ✔️ | ✔️ | ✔️ | |
x86_64-pc-windows-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-pc-windows-msvc | ✔️ | ✔️ | ✔️ |
SIMD支持
SIMD支持是在模块级别启用的。一般来说,过去十年发布的任何CPU都支持AVX2,从而启用所有可用优化。
较老的CPU(SSE2或更高版本)只能部分支持。您可以使用rq --version
检查具体启用了什么功能——查看SIMD支持
字段
$ rq --version
rq 0.9.1
Commit SHA: c024e1bab89610455537b77aed249d2a05a81ed6
Features: default,simd
Opt level: 3
Target triple: x86_64-unknown-linux-gnu
Codegen flags: link-arg=-fuse-ld=lld
SIMD support: avx2;fast_quotes;fast_popcnt
fast_quotes
功能取决于pclmulqdq
指令,而fast_popcnt
取决于popcnt
指令。
注意事项和限制
JSONPath
并非所有选择器都受支持,请参阅上表中的支持表。
重复键
该引擎假定输入JSON中的每个对象都没有重复键。重复键的行为不一定稳定,但当前引擎将简单地匹配第一个这样的键。
$ rq '$.key' --json '{"key":"value","key":"other value"}'
"value"
Unicode
该引擎在成员名称中不解析Unicode转义序列。这意味着键"a"
与键"\u0041"
不同,尽管从语义上看它们表示相同的字符串。这实际上是按照当前JSONPath规范设计的。解析Unicode序列的成本很高,因此为了高性能,该功能被推迟。这已记录在#117。
贡献
关键是:Fork,实现,创建PR返回此处。更多细节请参阅CONTRIBUTING文档。
构建和测试
开发工作流程使用just
。使用包含的Justfile
。如果检测到环境中没有Cargo,它将自动使用rustup
工具为您安装Rust。
$ just build
...
$ just test
...
基准测试
rsonpath
的基准测试位于一个独立的仓库中,在这个主仓库中作为一个 git 子模块。
运行所有基准测试的最简单方法是 just bench
。有关详细信息,请参阅子模块中的 README。
背景
我们有一篇关于 rsonpath
的论文将在 ASPLOS '24 上发表!您可以在这里阅读。
这个项目是我论文的构思。您可以通过阅读它来了解引擎的理论背景和其实施细节。
依赖项
显示直接依赖关系,完整的图示见下方。
cargo tree --package rsonpath --edges normal --depth 1
rsonpath v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath)
├── clap v4.5.4
├── color-eyre v0.6.3
├── eyre v0.6.12
├── log v0.4.21
├── rsonpath-lib v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
└── simple_logger v4.3.3
[build-dependencies]
├── rustflags v0.1.5
└── vergen v8.3.1
[build-dependencies]
cargo tree --package rsonpath-lib --edges normal --depth 1
rsonpath-lib v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
├── arbitrary v1.3.2
├── cfg-if v1.0.0
├── log v0.4.21
├── memmap2 v0.9.4
├── nom v7.1.3
├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
├── smallvec v1.13.2
├── static_assertions v1.1.0
├── thiserror v1.0.58
└── vector-map v1.0.1
理由
clap
– 提供CLI的标准crate。color-eyre
,eyre
– 为解析器提供更易于访问的错误信息。log
,simple-logger
– 编译和执行期间的诊断日志。cfg-if
– 用于支持SIMD和非SIMD版本。memmap2
– 通过内存映射快速读取源文件,而不是通过缓冲区副本。nom
– 用于解析器实现。smallvec
– 对于小栈性能至关重要。static_assertions
– 通过在编译时验证某些常量假设来提供额外的可靠性。thiserror
– 习惯性的Error
实现。vector_map
– 在查询编译器中使用,以提高性能。
完整的依赖关系树
cargo tree --package rsonpath --edges normal
rsonpath v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath)
├── clap v4.5.4
│ ├── clap_builder v4.5.2
│ │ ├── anstream v0.6.13
│ │ │ ├── anstyle v1.0.6
│ │ │ ├── anstyle-parse v0.2.3
│ │ │ │ └── utf8parse v0.2.1
│ │ │ ├── anstyle-query v1.0.2
│ │ │ │ └── windows-sys v0.52.0
│ │ │ │ └── windows-targets v0.52.4
│ │ │ │ ├── windows_aarch64_gnullvm v0.52.4
│ │ │ │ ├── windows_aarch64_msvc v0.52.4
│ │ │ │ ├── windows_i686_gnu v0.52.4
│ │ │ │ ├── windows_i686_msvc v0.52.4
│ │ │ │ ├── windows_x86_64_gnu v0.52.4
│ │ │ │ ├── windows_x86_64_gnullvm v0.52.4
│ │ │ │ └── windows_x86_64_msvc v0.52.4
│ │ │ ├── anstyle-wincon v3.0.2
│ │ │ │ ├── anstyle v1.0.6
│ │ │ │ └── windows-sys v0.52.0 (*)
│ │ │ ├── colorchoice v1.0.0
│ │ │ └── utf8parse v0.2.1
│ │ ├── anstyle v1.0.6
│ │ ├── clap_lex v0.7.0
│ │ ├── strsim v0.11.1
│ │ └── terminal_size v0.3.0
│ │ ├── rustix v0.38.32
│ │ │ ├── bitflags v2.5.0
│ │ │ ├── errno v0.3.8
│ │ │ │ ├── libc v0.2.153
│ │ │ │ └── windows-sys v0.52.0 (*)
│ │ │ ├── libc v0.2.153
│ │ │ ├── linux-raw-sys v0.4.13
│ │ │ └── windows-sys v0.52.0 (*)
│ │ └── windows-sys v0.48.0
│ │ └── windows-targets v0.48.5
│ │ ├── windows_aarch64_gnullvm v0.48.5
│ │ ├── windows_aarch64_msvc v0.48.5
│ │ ├── windows_i686_gnu v0.48.5
│ │ ├── windows_i686_msvc v0.48.5
│ │ ├── windows_x86_64_gnu v0.48.5
│ │ ├── windows_x86_64_gnullvm v0.48.5
│ │ └── windows_x86_64_msvc v0.48.5
│ └── clap_derive v4.5.4 (proc-macro)
│ ├── heck v0.5.0
│ ├── proc-macro2 v1.0.79
│ │ └── unicode-ident v1.0.12
│ ├── quote v1.0.35
│ │ └── proc-macro2 v1.0.79 (*)
│ └── syn v2.0.58
│ ├── proc-macro2 v1.0.79 (*)
│ ├── quote v1.0.35 (*)
│ └── unicode-ident v1.0.12
├── color-eyre v0.6.3
│ ├── backtrace v0.3.71
│ │ ├── addr2line v0.21.0
│ │ │ └── gimli v0.28.1
│ │ ├── cfg-if v1.0.0
│ │ ├── libc v0.2.153
│ │ ├── miniz_oxide v0.7.2
│ │ │ └── adler v1.0.2
│ │ ├── object v0.32.2
│ │ │ └── memchr v2.7.2
│ │ └── rustc-demangle v0.1.23
│ │ [build-dependencies]
│ │ └── cc v1.0.90
│ ├── eyre v0.6.12
│ │ ├── indenter v0.3.3
│ │ └── once_cell v1.19.0
│ ├── indenter v0.3.3
│ ├── once_cell v1.19.0
│ └── owo-colors v3.5.0
├── eyre v0.6.12 (*)
├── log v0.4.21
├── rsonpath-lib v0.9.1 (/home/mat/src/rsonpath/crates/rsonpath-lib)
│ ├── cfg-if v1.0.0
│ ├── log v0.4.21
│ ├── memmap2 v0.9.4
│ │ └── libc v0.2.153
│ ├── nom v7.1.3
│ │ ├── memchr v2.7.2
│ │ └── minimal-lexical v0.2.1
│ ├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax)
│ │ ├── nom v7.1.3 (*)
│ │ ├── owo-colors v4.0.0
│ │ ├── thiserror v1.0.58
│ │ │ └── thiserror-impl v1.0.58 (proc-macro)
│ │ │ ├── proc-macro2 v1.0.79 (*)
│ │ │ ├── quote v1.0.35 (*)
│ │ │ └── syn v2.0.58 (*)
│ │ └── unicode-width v0.1.11
│ ├── smallvec v1.13.2
│ ├── static_assertions v1.1.0
│ ├── thiserror v1.0.58 (*)
│ └── vector-map v1.0.1
│ ├── contracts v0.4.0 (proc-macro)
│ │ ├── proc-macro2 v1.0.79 (*)
│ │ ├── quote v1.0.35 (*)
│ │ └── syn v1.0.109
│ │ ├── proc-macro2 v1.0.79 (*)
│ │ ├── quote v1.0.35 (*)
│ │ └── unicode-ident v1.0.12
│ └── rand v0.7.3
│ ├── getrandom v0.1.16
│ │ ├── cfg-if v1.0.0
│ │ ├── libc v0.2.153
│ │ └── wasi v0.9.0+wasi-snapshot-preview1
│ ├── libc v0.2.153
│ ├── rand_chacha v0.2.2
│ │ ├── ppv-lite86 v0.2.17
│ │ └── rand_core v0.5.1
│ │ └── getrandom v0.1.16 (*)
│ ├── rand_core v0.5.1 (*)
│ └── rand_hc v0.2.0
│ └── rand_core v0.5.1 (*)
├── rsonpath-syntax v0.3.1 (/home/mat/src/rsonpath/crates/rsonpath-syntax) (*)
└── simple_logger v4.3.3
├── colored v2.1.0
│ ├── lazy_static v1.4.0
│ └── windows-sys v0.48.0 (*)
├── log v0.4.21
├── time v0.3.34
│ ├── deranged v0.3.11
│ │ └── powerfmt v0.2.0
│ ├── itoa v1.0.11
│ ├── libc v0.2.153
│ ├── num-conv v0.1.0
│ ├── num_threads v0.1.7
│ │ └── libc v0.2.153
│ ├── powerfmt v0.2.0
│ ├── time-core v0.1.2
│ └── time-macros v0.2.17 (proc-macro)
│ ├── num-conv v0.1.0
│ └── time-core v0.1.2
└── windows-sys v0.48.0 (*)
[build-dependencies]
├── rustflags v0.1.5
└── vergen v8.3.1
├── anyhow v1.0.81
├── cargo_metadata v0.18.1
│ ├── camino v1.1.6
│ │ └── serde v1.0.197
│ │ └── serde_derive v1.0.197 (proc-macro)
│ │ ├── proc-macro2 v1.0.79 (*)
│ │ ├── quote v1.0.35 (*)
│ │ └── syn v2.0.58 (*)
│ ├── cargo-platform v0.1.8
│ │ └── serde v1.0.197 (*)
│ ├── semver v1.0.22
│ │ └── serde v1.0.197 (*)
│ ├── serde v1.0.197 (*)
│ ├── serde_json v1.0.115
│ │ ├── itoa v1.0.11
│ │ ├── ryu v1.0.17
│ │ └── serde v1.0.197 (*)
│ └── thiserror v1.0.58 (*)
├── cfg-if v1.0.0
├── regex v1.10.4
│ ├── aho-corasick v1.1.3
│ │ └── memchr v2.7.2
│ ├── memchr v2.7.2
│ ├── regex-automata v0.4.6
│ │ ├── aho-corasick v1.1.3 (*)
│ │ ├── memchr v2.7.2
│ │ └── regex-syntax v0.8.3
│ └── regex-syntax v0.8.3
├── rustc_version v0.4.0
│ └── semver v1.0.22 (*)
└── time v0.3.34
├── deranged v0.3.11 (*)
├── itoa v1.0.11
├── libc v0.2.153
├── num-conv v0.1.0
├── num_threads v0.1.7 (*)
├── powerfmt v0.2.0
└── time-core v0.1.2
[build-dependencies]
└── rustversion v1.0.14 (proc-macro)
依赖项
~8–19MB
~263K SLoC