Mecanismo JSONPath experimental para consultar conjuntos de dados transmitidos em massa.
A caixa rsonpath
fornece um analisador JSONPath e um mecanismo de execução de consulta rq
, que utiliza instruções SIMD para fornecer melhorias massivas de rendimento em relação aos mecanismos convencionais.
Benchmarks de rsonpath
em relação a um mecanismo não-SIMD de referência no conjunto de dados Pison. NOTA: A escala é logarítmica!
Para executar uma consulta JSONPath em um arquivo, execute:
rq '$..a.b' ./file.json
Se o arquivo for omitido, o mecanismo lê a entrada padrão. JSON também pode ser passado in-line:
$ rq ' $..a.b ' --json ' {"c":{"a":{"b":42}}} '
42
Para detalhes, consulte rq --help
ou o rsonbook.
O resultado da execução de uma consulta é uma sequência de valores correspondentes, delimitados por novas linhas. Alternativamente, passar --result count
retorna apenas o número de correspondências, o que pode ser muito mais rápido. Para outros modos de resultados consulte a página de uso --help
.
Consulte Versões para binários pré-compilados para todos os destinos de suporte de primeira classe.
cargo
A maneira mais fácil de instalar é via cargo
.
$ cargo install rsonpath
...
Se a velocidade máxima for fundamental, você deve instalar rsonpath
com suporte nativo às instruções da CPU. Isso resultará em um binário que não é portátil e pode funcionar incorretamente em qualquer outra máquina, mas irá espremer até o último bit de rendimento.
Para fazer isso, execute a seguinte variante cargo install
:
$ RUSTFLAGS= " -C target-cpu=native " cargo install rsonpath
...
Confira o capítulo relevante no rsonbook.
O projeto está sendo desenvolvido ativamente e atualmente oferece suporte apenas a um subconjunto da linguagem de consulta JSONPath. Uma consulta é uma sequência de segmentos, cada um contendo um ou mais seletores.
Segmento | Sintaxe | Suportado | Desde | Problema de rastreamento |
---|---|---|---|---|
Segmento filho (único) | [<selector>] | ✔️ | v0.1.0 | |
Segmento filho (múltiplo) | [<selector1>,...,<selectorN>] | |||
Segmento descendente (único) | ..[<selector>] | ✔️ | v0.1.0 | |
Segmento descendente (múltiplo) | ..[<selector1>,...,<selectorN>] |
Seletor | Sintaxe | Suportado | Desde | Problema de rastreamento |
---|---|---|---|---|
Raiz | $ | ✔️ | v0.1.0 | |
Nome | .<member> , [<member>] | ✔️ | v0.1.0 | |
Curinga | .* , ..* , [*] | ✔️ | v0.4.0 | |
Índice (índice de matriz) | [<index>] | ✔️ | v0.5.0 | |
Índice (índice da matriz do final) | [-<index>] | |||
Fatia de matriz (forward, limites positivos) | [<start>:<end>:<step>] | ✔️ | v0.9.0 | #152 |
Fatia da matriz (limites diretos e arbitrários) | [<start>:<end>:<step>] | |||
Fatia de matriz (retrocesso, limites arbitrários) | [<start>:<end>:-<step>] | |||
Filtros – testes existenciais | [?<path>] | #154 | ||
Filtros – comparações de átomos const | [?<path> <binop> <atom>] | #156 | ||
Filtros – expressões lógicas | && , || , ! | |||
Filtros – aninhamento | [?<expr>[?<expr>]...] | |||
Filtros – comparações arbitrárias | [?<path> <binop> <path>] | |||
Filtros – extensões de função | [?func(<path>)] |
A caixa é construída continuamente para todos os alvos Rust Tier 1, e os testes são executados continuamente para alvos que podem ser executados com imagens de ação do GitHub. SIMD é compatível apenas com plataformas x86/x86_64.
Alvo triplo | compilação nosimd | Suporte SIMD | Testes contínuos | Problemas de rastreamento |
---|---|---|---|---|
aarch64-desconhecido-linux-gnu | ✔️ | ✔️ | #21, #115 | |
i686-desconhecido-linux-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-desconhecido-linux-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-apple-darwin | ✔️ | ✔️ | ✔️ | |
i686-pc-windows-gnu | ✔️ | ✔️ | ✔️ | |
i686-pc-windows-msvc | ✔️ | ✔️ | ✔️ | |
x86_64-pc-windows-gnu | ✔️ | ✔️ | ✔️ | |
x86_64-pc-windows-msvc | ✔️ | ✔️ | ✔️ |
O suporte SIMD é habilitado módulo por módulo. Geralmente, qualquer CPU lançada na última década suporta AVX2, o que permite todas as otimizações disponíveis.
CPUs mais antigas com SSE2 ou superior obtêm suporte parcial. Você pode verificar o que exatamente está habilitado com rq --version
– verifique o campo SIMD support
:
$ 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
A capacidade fast_quotes
depende da instrução pclmulqdq
e fast_popcnt
da instrução popcnt
.
Nem todos os seletores são suportados, consulte a tabela de suporte acima.
O mecanismo pressupõe que cada objeto no JSON de entrada não possui chaves duplicadas. Não é garantido que o comportamento em chaves duplicadas seja estável, mas atualmente o mecanismo simplesmente corresponderá à primeira chave desse tipo.
$ rq ' $.key ' --json ' {"key":"value","key":"other value"} '
"value"
O mecanismo não analisa sequências de escape Unicode em nomes de membros. Isso significa que uma chave "a"
é diferente de uma chave "u0041"
, embora semanticamente representem a mesma string. Na verdade, isso foi projetado em relação à especificação JSONPath atual. A análise de sequências Unicode é cara, então o suporte para isso foi adiado em favor do alto desempenho. Isso é rastreado como #117.
A essência é: bifurcar, implementar, fazer um PR aqui. Mais detalhes estão no documento CONTRIBUINDO.
O fluxo de trabalho de desenvolvimento utiliza just
arquivos . Use o Justfile
incluído. Ele instalará automaticamente o Rust para você usando a ferramenta rustup
se detectar que não há Cargo em seu ambiente.
$ just build
...
$ just test
...
Os benchmarks para rsonpath
estão localizados em um repositório separado, incluído como um submódulo git neste repositório principal.
A maneira mais fácil de executar todos os benchmarks é just bench
. Para obter detalhes, consulte o README no submódulo.
Temos um artigo sobre rsonpath
a ser publicado na ASPLOS '24! Você pode ler aqui.
Este projeto foi concebido como minha tese. Você pode lê-lo para obter detalhes sobre a base teórica do motor e detalhes de sua implementação.
Mostrando dependências diretas, para gráfico completo veja abaixo.
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
– caixa padrão para fornecer a CLI.color-eyre
, eyre
– mensagens de erro mais acessíveis para o analisador.log
, simple-logger
– logs de diagnóstico durante a compilação e execução.cfg-if
– usado para suportar versões SIMD e não SIMD.memmap2
– para leitura rápida de arquivos de origem através de um mapa de memória em vez de cópias em buffer.nom
– para implementação do analisador.smallvec
– crucial para o desempenho de pilhas pequenas.static_assertions
– confiabilidade adicional por algumas suposições constantes validadas em tempo de compilação.thiserror
– implementações Error
idiomáticos.vector_map
– usado no compilador de consulta para um desempenho mensuravelmente melhor. 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)