Crate serde_json_borrow

Source
Expand description

§Serde JSON Borrowed

Parses JSON into serde_json_borrow::Value<'ctx> from &'ctx str.

The default serde_json parses into an owned serde_json::Value. In cases where the DOM representation is just an intermediate struct, parsing into owned serde_json::Value can cause a lot of overhead. serde_json_borrow::Value<'ctx> borrows the Strings instead.

Additionally it pushes the (key,value) for JSON objects into a Vec instead of putting the values into a BTreeMap. Access works via ObjectAsVec, which provides the same API as BTreeMap.

The primary benefit of using serde_json_borrow is a higher JSON deserialization performance due to less allocations. By borrowing a DOM, the library ensures that no additional memory is allocated for Strings, that contain no JSON escape codes.

§Usage

use std::io;
fn main() -> io::Result<()> {
    let data: &str = r#"{"bool": true, "key": "123"}"#;
    // Note that serde_json_borrow::Value<'ctx> is tied to the lifetime of data.
    let value: serde_json_borrow::Value = serde_json::from_str(&data)?;
    assert_eq!(value.get("bool"), &serde_json_borrow::Value::Bool(true));
    assert_eq!(value.get("key"), &serde_json_borrow::Value::Str("123".into()));
    // Using OwnedValue will take ownership of the String.
    let value: serde_json_borrow::OwnedValue = serde_json_borrow::OwnedValue::from_str(&data)?;
    assert_eq!(value.get("bool"), &serde_json_borrow::Value::Bool(true));
    assert_eq!(value.get("key"), &serde_json_borrow::Value::Str("123".into()));
    Ok(())
}

§OwnedValue

You can take advantage of OwnedValue to parse a String containing unparsed JSON into a Value without having to worry about lifetimes, as OwnedValue will take ownership of the String and reference slices of it, rather than making copies.

§Limitations

The feature flag cowkeys uses Cow<str> instead of &str as keys in objects. This enables support for escaped data in keys. Without the cowkeys feature flag &str is used, which does not allow any JSON escaping characters in keys.

List of unsupported characters (https://www.json.org/json-en.html) in object keys without cowkeys feature flag.

\" represents the quotation mark character (U+0022).
\\ represents the reverse solidus character (U+005C).
\/ represents the solidus character (U+002F).
\b represents the backspace character (U+0008).
\f represents the form feed character (U+000C).
\n represents the line feed character (U+000A).
\r represents the carriage return character (U+000D).
\t represents the character tabulation character (U+0009).

§Performance

Performance gain depends on how many allocations can be avoided, and how many objects there are, as deserializing into a vec is significantly faster.

The benchmarks in the github repository show around 1.8x speedup, although they don’t account for that in practice it won’t be a simple consecutive alloc json, dealloc json. There will be other allocations in between.

On a hadoop file system log data set benchmark, I get 714Mb/s JSON deserialization throughput on my machine.

Structs§

Map
Represents a JSON key/value type.
ObjectAsVec
Represents a JSON key/value type.
OwnedValue
Parses a String into Value, by taking ownership of String and reference slices from it.

Enums§

Value
Represents any valid JSON value.

Type Aliases§

KeyStrType
The string type used. Can be toggled between &str and Cow<str> via cowstr feature flag