有效地将大型矢量分割成矢量

时间:2019-01-29 05:11:22

标签: vector rust iterator slice

我想将一个大向量分成多个向量。我知道chunks(),但是不确定从迭代器到2D Vec的最佳方法。我发现下面的方法可以工作,但是有没有更好的方法可以写呢?

let v: Vec<i32> = vec![1,1,1,2,2,2,3,3,3];
let v_chunked: Vec<Vec<i32>> = v.chunks(3).map(|x| x.to_vec()).collect();

println!("{:?}", v_chunked); // [[1, 1, 1], [2, 2, 2], [3, 3, 3]]

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5031d4d0e43470242b8304d483967a25

更新:最初的问题有点广泛。与上面的示例类似的操作是分析后程序最慢的部分之一,我想知道如何改进它。在注释的帮助下,我发现将数据作为1D vec存储在我的结构中效率更高。然后为了方便地处理它,我使用了块,并根据需要在函数体内使用了切片的vec。

2 个答案:

答案 0 :(得分:1)

如果您确实想要Vec<Veci32>>,那么这是一种很好的方法。任何其他方法(不包括unsafe代码,请参见下文)都不太可能显着提高速度或使用明显更少的内存。不管实际的代码是什么,每个嵌套的Vec都是一个新的内存分配,所有数据都需要复制-这实际上就是您的代码要做的所有事情。

表示这种2D结构的一种更为“鲁棒”的方式是将Vec切成原始数据。这样一来,您就不会进行任何复制,也不会进行新的分配。

let v_slices: Vec<&[i32]> = v.chunks(3).collect();

println!("{:?}", v_slices); // [[1, 1, 1], [2, 2, 2], [3, 3, 3]]

编辑:我在这里确实有一个extra bit和一些unsafe代码,可以将Vec<i32>转换为Vec<Vec<i32>>重新分配。但是,已经指出它仍然具有未定义的行为,并且该问题从根本上讲是not fixable

答案 1 :(得分:0)

借助注释,我发现将数据存储为1D Vec效率更高。然后为了方便地处理它,我使用chunks并使用数据在功能体内根据需要使用切片的Vec