我想将一个大向量分成多个向量。我知道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]]
类似于该操作的操作是分析后我程序中最慢的部分之一,我想知道如何改进它。
如果您真正想要的是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
[借助注释,我发现将数据存储为1D Vec
效率更高。然后,为了方便地处理它,我使用chunks
并根据需要在函数体内使用数据使用切片的Vec
。