【发布时间】:2019-05-10 11:42:49
【问题描述】:
Stack Overflow 上已经有几个关于在堆上分配数组(比如[i32])的问题。一般建议是拳击,例如Box<[i32]>。但是,虽然装箱对于较小的数组来说足够好,但问题是被装箱的数组必须首先在堆栈上分配。
因此,如果数组太大(例如 1000 万个元素),即使使用装箱,您也会出现堆栈溢出(不太可能有那么大的堆栈)。
然后建议改用Vec<T>,在我们的示例中为Vec<i32>。虽然这确实起到了作用,但它确实会对性能产生影响。
考虑以下程序:
fn main() {
const LENGTH: usize = 10_000;
let mut a: [i32; LENGTH] = [0; LENGTH];
for j in 0..LENGTH {
for i in 0..LENGTH {
a[i] = j as i32;
}
}
}
time 告诉我这个程序运行大约需要 2.9 秒。我在这个例子中使用了 10'000,所以我可以在堆栈上分配它,但我真的想要一个有 1000 万的。
现在考虑相同的程序,但改用Vec<T>:
fn main() {
const LENGTH: usize = 10_000;
let mut a: Vec<i32> = vec![0; LENGTH];
for j in 0..LENGTH {
for i in 0..LENGTH {
a[i] = j as i32;
}
}
}
time 告诉我这个程序需要大约 5 秒才能运行。现在time 不是很精确,但是对于这样一个简单的程序来说,大约 2 秒的差异并不是一个微不足道的影响。
存储就是存储,带数组的程序在装箱的情况下也一样快。所以不是堆减慢了Vec<T> 版本,而是Vec<T> 结构本身。
我也尝试使用HashMap(特别是HashMap<usize, i32> 来模拟数组结构),但这比Vec<T> 解决方案要慢得多。
如果我的LENGTH 是 1000 万,第一个版本甚至都不会运行。
如果这不可能,那么是否有一种结构在堆上的行为类似于数组(和Vec<T>),但可以匹配数组的速度和性能?
【问题讨论】:
-
Stack Overflow 上已经有几个关于分配数组的问题 — 这个 有何不同?仅仅因为您不喜欢现有答案并不意味着您可以打开副本。
-
@Shepmaster 我的问题也是关于性能的。其他问题从未提出过这个问题。下面的答案也探讨了这方面,回答的很好。
标签: arrays rust heap-memory