6 个版本

0.2.0 2024年5月27日
0.1.4 2024年4月11日
0.1.3 2023年11月20日
0.1.2 2023年10月30日

#230编码

Download history 1885/week @ 2024-04-28 3442/week @ 2024-05-05 2908/week @ 2024-05-12 2611/week @ 2024-05-19 1416/week @ 2024-05-26 996/week @ 2024-06-02 765/week @ 2024-06-09 820/week @ 2024-06-16 606/week @ 2024-06-23 1071/week @ 2024-06-30 830/week @ 2024-07-07 901/week @ 2024-07-14 623/week @ 2024-07-21 699/week @ 2024-07-28 546/week @ 2024-08-04 845/week @ 2024-08-11

2,754 每月下载量
用于 sql-json-path

Apache-2.0

105KB
2K SLoC

jsonbb

Crate Docs

jsonbb 是 JSON 值的二进制表示,灵感来自 PostgreSQL 中的 JSONB,并优化于快速解析。

用法

jsonbb 提供与 serde_json 相似的 API,用于构建和查询 JSON 值。

// Deserialize a JSON value from a string of JSON text.
let value: jsonbb::Value = r#"{"name": ["foo", "bar"]}"#.parse().unwrap();

// Serialize a JSON value into JSON text.
let json = value.to_string();
assert_eq!(json, r#"{"name":["foo","bar"]}"#);

作为一个二进制格式,你可以从中提取字节切片,或者从字节切片中读取 JSON 值。

// Get the underlying byte slice of a JSON value.
let jsonbb = value.as_bytes();

// Read a JSON value from a byte slice.
let value = jsonbb::ValueRef::from_bytes(jsonbb);

你可以使用常见的 API 查询 JSON,然后使用 Builder API 构建新的 JSON 值。

// Indexing
let name = value.get("name").unwrap();
let foo = name.get(0).unwrap();
assert_eq!(foo.as_str().unwrap(), "foo");

// Build a JSON value.
let mut builder = jsonbb::Builder::<Vec<u8>>::new();
builder.begin_object();
builder.add_string("name");
builder.add_value(foo);
builder.end_object();
let value = builder.finish();
assert_eq!(value.to_string(), r#"{"name":"foo"}"#);

格式

jsonbb 在连续内存中存储 JSON 值。通过避免动态内存分配,它更加缓存友好,并提供高效的 解析查询 性能。

它具有以下关键特性

  1. 内存连续性:任何 JSON 子树的 内容都连续存储,允许通过 memcpy 进行高效的复制。这导致了非常高效的索引操作。
  2. 后序遍历:JSON 节点按后序遍历顺序存储。当解析 JSON 字符串时,输出可以顺序写入缓冲区,无需额外的内存分配和移动。这导致了非常高效的解析操作。

性能比较

item[^0] jsonbb jsonb serde_json simd_json
canada.parse() 4.7394 ms 12.640 ms 10.806 ms 6.0767 ms [^1]
canada.to_json() 5.7694 ms 20.420 ms 5.5702 ms 3.0548 ms
canada.size() 2,117,412 B 1,892,844 B
canada["type"][^2] 39.181 ns[^2.1] 316.51 ns[^2.2] 67.202 ns [^2.3] 27.102 ns [^2.4]
citm_catalog["areaNames"] 92.363 ns 328.70 ns 2.1190 µs [^3] 1.9012 µs [^3]
from("1234567890") 26.840 ns 91.037 ns 45.130 ns 21.513 ns
a==b 66.513 ns 115.89 ns 39.213 纳秒 41.675 纳秒
a<b 71.793 纳秒 120.77 纳秒 不支持 不支持

[^0]:基准测试的 JSON 文件:canadacitm_catalog

[^1]:解析为 simd_json::OwnedValue 以确保公平。

[^2]:canada["type"] 返回一个字符串,因此该操作的主要开销在于索引。

[^2.1]:jsonbb 使用二分搜索对排序键进行搜索 [^2.2]:jsonb 使用线性搜索对未排序键进行搜索 [^2.3]:serde_json 使用 BTreeMap [^2.4]:simd_json 使用 HashMap

[^3]:citm_catalog["areaNames"] 返回一个包含 17 个键值字符串对的对象。然而,由于每个字符串都进行动态内存分配,serde_jsonsimd_json 的性能较慢。相比之下,jsonb 采用平面表示,允许直接进行memcpy操作,从而提高性能。

依赖项

~0.7–2.3MB
~43K SLoC