使用Serde和Bincode将大型结构体序列化到磁盘上是缓慢的

14

我有一个包含2³¹个u32值的向量的结构体(总大小约为8GB)。我按照bincode示例将其写入磁盘:

#[macro_use]
extern crate serde_derive;
extern crate bincode;

use std::fs::File;
use bincode::serialize_into;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct MyStruct {
    counter: Vec<u32>,
    offset: usize,
}

impl MyStruct {
    // omitted for conciseness
}


fn main() {
    let m = MyStruct::new();

    // fill entries in the counter vector

    let mut f = File::create("/tmp/foo.bar").unwrap();
    serialize_into(&mut f, &m).unwrap();
}
为避免重复分配内存,我使用了 serialize_into 直接写入文件。但是,写入过程非常缓慢(大约需要半小时)。有什么方法可以加快速度吗?
为避免重复分配内存,我使用了 serialize_into 直接写入文件。但是,写入速度非常缓慢(大约需要半个小时)。是否有方法可以提高速度?
1个回答

17

这不是serde和/或bincode的问题。与其他某些语言不同,Rust默认情况下不使用缓冲I/O(有关详情,请参见此问题)。因此,通过使用缓冲区写入器,可以显着提高代码的性能:


#[macro_use]
extern crate serde_derive;
extern crate bincode;

use std::fs::File;
use bincode::serialize_into;
use std::io::BufWriter;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct MyStruct {
    counter: Vec<u32>,
    offset: usize,
}

impl MyStruct {
    // omitted for conciseness
}


fn main() {
    let m = MyStruct::new();

    // fill entries in the counter vector

    let mut f = BufWriter::new(File::create("/tmp/foo.bar").unwrap());
    serialize_into(&mut f, &m).unwrap();
}

对我来说,这将写作过程加快了从大约半个小时到40秒(加速50倍)。


1
我认为这个问题可能会被关闭,因为核心问题是相同的,与您链接的那个问题重复。 - ljedrz
7
也许,但我花了一些时间才找出问题所在。因此,对于那些来自 serde/ bincode 方面的人来说,这可能会更容易找到问题所在。 - m00am
1
我总是忘记这个,虽然我应该知道...哦,谢谢。 - Johannes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接