#json #json-query #json-path #query #json-parser #query-engine #json-key

app rsonpath

由SIMD驱动的闪电般的JSONPath CLI工具

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解析实现

MIT 许可证

785KB
16K SLoC

rsonpath – SIMD驱动的JSONPath 🚀

Rust docs.rs Book

OpenSSF Best Practices OpenSSF Scorecard fuzzing

Crates.io GitHub Release Date GitHub last commit

MSRV License

用于查询大量流式数据集的实验性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 --helprsonbook

结果

查询运行的结果是一系列匹配值,由换行符分隔。或者,传递 --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-eyreeyre – 为解析器提供更易于访问的错误信息。
  • logsimple-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