gpt4 book ai didi

rust - 我可以将RMPV `Value`发送回rmp_serde进行反序列化吗?

转载 作者:行者123 更新时间:2023-12-03 11:46:47 26 4
gpt4 key购买 nike

我有一个很大的,有点复杂的数据结构,可以使用serdermp-serde进行序列化和反序列化,但是我发现反序列化非常慢。我认为这是因为我的数据结构包含两个相当大的HashMap。我不知道rmp_serde::from_slice创建HashMap的效率如何-它会使用.with_capacity进行初始化还是只是创建一个HashMap并一一插入?此外,我发现AHashMap在其他地方也给我带来了相当大的性能改进,因此我试图避免使用默认的HashMap。
我想尝试使用 rmpv::decode::value::read_value 反序列化,但我想将大部分反序列化工作留给rmp_serde,而我自己给一些 Value 来实现一些反序列化。有没有办法选择我手动反序列化的片段?
从概念上讲,我想做的是:

let v = rmp::decode::read_value(&mut reader).unwrap();   // get some Value
let arr : &Vec<Value> = v.as_array().unwrap(); // v is known to be an array
let first_value : MyType = deserialize_manually(arr[0]); // I'll convert the Value myself
let second_value : AnotherType = arr[1].into(); // allow rmpv to convert Value for me
我目前正在使用rmp-serde 0.14和rmpv 0.4.7。 The rmp_serde changelogrmp_serde release page没有提供更改的详细信息,因此我没有理由相信升级到当前版本(撰写本文时为v0.15.4)将提供任何新功能。
我知道serde提供了 deserialize_with attribute。也许这是一条合适的路线,所以替代地,我的问题是:如何使用 deserialize_with反序列化特定的MsgPack字段?

最佳答案

我能够使用deserialize-with使它正常工作。首先,我必须注释我的结构:

struct MyStruct {
some_number: i32,
#[serde(deserialize_with="de_first_value")]
first_value : HashMap<i32, String>, // T1 & T2 don't matter
second_value : AnotherType,
}
然后,我创建此函数来驱动反序列化。因为我要反序列化 HashMap,所以我遵循serde的 Implement Deserialize for a custom map type:
fn de_first_value<'de, D>(deserializer: D) -> Result<HashMap<i32, String>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
deserializer.deserialize_byte_buf(MyHmVisitor)
}
然后定义 MyHmVisitor并实现 the Visitor trait。为了反序列化HashMap,我必须实现 visit_map函数;我假设可以通过实现 the default provided methods来以其他方式对其他类型进行类似的反序列化(除非重写,否则所有操作都会因类型错误而失败):
struct MyHmVisitor;

impl<'de> serde::de::Visitor<'de> for MyHmVisitor {
type Value = HashMap<i32, String>;

/// "This is used in error messages. The message should complete the sentence
/// 'This Visitor expects to receive ...'"
/// https://docs.serde.rs/src/serde/de/mod.rs.html#1270
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a HashMap<i32, String>")
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
// extract the size hint from the serialized map. If it doesn't exist, default to 0
let capacity = map.size_hint().unwrap_or(0);

let mut hm = HashMap::with_capacity(capacity);

while let Some((k, v)) = map.next_entry()? {
hm.insert(k,v);
}

hm
}
}

关于rust - 我可以将RMPV `Value`发送回rmp_serde进行反序列化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66034100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com