将大向量有效地分割为向量的向量

问题描述 投票:2回答:2

我想将一个大向量分成多个向量。我知道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

类似于该操作的操作是分析后我程序中最慢的部分之一,我想知道如何改进它。

vector rust iterator slice
2个回答
3
投票

如果您真正想要的是Vec<Vec<i32>>,那么这是一种很好的方法。任何其他方法(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]]

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.