使用 Serde JSON 为什么“{c:[{}]}”在反序列化为 RawValue 结构时会导致堆分配?
With Serde JSON why does "{c:[{}]}" cause a heap allocation when deserializing into a RawValue struct?
我正在尝试了解堆分配在 Serde 中的工作原理 JSON。
为什么下面的代码会进行一次堆分配?我期望没有分配,因为 c
的值是使用 `#[serde(borrow)].
借来的 serde_json::value::RawValue
#[derive(Deserialize, Debug)]
struct MyStruct<'a> {
#[serde(borrow)]
c: &'a serde_json::value::RawValue,
}
fn main() {
let msg = r#"{"c":[{}]}"#;
// One unexpected allocation here.
serde_json::from_str::<MyStruct>(msg).unwrap();
}
请注意,例如使用 {"c":[2, 3]}
而不是 {"c":[{}]}
将导致没有分配。
我怎样才能使反序列化为 MyStruct
时分配为零?
你无法避免分配。解析器需要在堆上分配一些内存,因为 JSON 对象和数组可以任意深度嵌套,并且它需要跟踪当前正在解析的值的类型。
我 modified your program 对解析过程中发生的第一次堆分配感到恐慌(因为我懒得调试,操场上没有调试器)。回溯显示堆分配的来源。关键帧是这个:
14: serde_json::de::Deserializer<R>::ignore_value
at ./.cargo/registry/src/github.com-1ecc6299db9ec823/serde_json-1.0.69/src/de.rs:1049:21
您可以确定您的 MyStruct
不会指向堆分配的内存,因为您的结构包含共享引用而不是拥有的值(并且输入是静态字符串)。为了 c
引用堆分配的内存,serde_json
必须 leak 它(但它并没有这样做;如果每次解析都可能泄漏内存,那就太糟糕了! ).
分配是 serde_json
的内部分配,将在返回前释放。有一个内部暂存区可能需要分配 (source)。
serde_json
的 README 也提到它依赖于 alloc 支持,所以分配并不意外:
As long as there is a memory allocator, it is possible to use serde_json without the rest of the Rust standard library.
如果您需要在没有分配的情况下工作,您可以尝试 serde-json-core,README 中也提到了这一点。
我正在尝试了解堆分配在 Serde 中的工作原理 JSON。
为什么下面的代码会进行一次堆分配?我期望没有分配,因为 c
的值是使用 `#[serde(borrow)].
serde_json::value::RawValue
#[derive(Deserialize, Debug)]
struct MyStruct<'a> {
#[serde(borrow)]
c: &'a serde_json::value::RawValue,
}
fn main() {
let msg = r#"{"c":[{}]}"#;
// One unexpected allocation here.
serde_json::from_str::<MyStruct>(msg).unwrap();
}
请注意,例如使用 {"c":[2, 3]}
而不是 {"c":[{}]}
将导致没有分配。
我怎样才能使反序列化为 MyStruct
时分配为零?
你无法避免分配。解析器需要在堆上分配一些内存,因为 JSON 对象和数组可以任意深度嵌套,并且它需要跟踪当前正在解析的值的类型。
我 modified your program 对解析过程中发生的第一次堆分配感到恐慌(因为我懒得调试,操场上没有调试器)。回溯显示堆分配的来源。关键帧是这个:
14: serde_json::de::Deserializer<R>::ignore_value
at ./.cargo/registry/src/github.com-1ecc6299db9ec823/serde_json-1.0.69/src/de.rs:1049:21
您可以确定您的 MyStruct
不会指向堆分配的内存,因为您的结构包含共享引用而不是拥有的值(并且输入是静态字符串)。为了 c
引用堆分配的内存,serde_json
必须 leak 它(但它并没有这样做;如果每次解析都可能泄漏内存,那就太糟糕了! ).
分配是 serde_json
的内部分配,将在返回前释放。有一个内部暂存区可能需要分配 (source)。
serde_json
的 README 也提到它依赖于 alloc 支持,所以分配并不意外:
As long as there is a memory allocator, it is possible to use serde_json without the rest of the Rust standard library.
如果您需要在没有分配的情况下工作,您可以尝试 serde-json-core,README 中也提到了这一点。