Rust向量(`Vec<T>`)与数组(`[T; n]`)的性能比较

32
在Rust中,使用向量与数组相比,性能损失有多大?
在这里的“性能”是指:元素访问的速度或迭代的速度。
1个回答

43
他们都在一个线性连续的数组中存储数据,访问或迭代都是O(1)操作,因此性能没有区别。唯一的情况是vector可能比一些小列表慢,因为数组存储在当前堆栈帧的堆栈上,因此它们的数据很可能已经加载到CPU缓存中。相反,vector将数据存储在堆上,因此在首次访问之前数据不会在缓存中可用。
另外,vector还有一个间接级别,因为您需要先加载数组的地址,因此第一个内存访问可能也会变慢,但这只是微不足道的。
当使用向量的向量与多维数组时,另一个更糟糕的时间是每个向量都是单独分配的,并且散布在所有内存周围,这对缓存不利。请参见Access time of vec vs array 另请参见Difference between array vs. vec for memory and cpu usage

堆栈上的数组由于堆栈保护而变慢。是的,这很反直觉。唯一的问题是分配时间,如果你编写得当,它就不是问题,也不是本问题的范畴。 - Stargateur
1
@Stargateur Rust编译时通常会为堆栈变量提供特定的缓冲区溢出保护吗?我怀疑这是不正确的。在Rust中,安全代码默认情况下是内存安全的,并且所有索引访问都会进行检查,无论您要索引的数组是在堆栈还是堆上。 - Sven Marnach
@SvenMarnach 语言并不重要,很多 Rust 代码依赖于可能会破坏堆栈的外部库,但是 Rust 有这个选项(LLVM),可以添加来自操作系统的可能保护。在真实世界的应用中,使用数组而不是向量的原因非常少,堆栈将更慢、更危险且不够灵活。堆栈只应用于小型数组,而不是缓冲区。 - Stargateur
1
@Stargateur 我们似乎在谈论不同的事情。我指的是类似于 -fstack-protector-all 的软件堆栈保护,它会发出额外的代码来检测缓冲区溢出,并且据我所知与操作系统无关。这种保护在 Rust 中并没有太多意义,因为它对我们链接的任何 C 库都没有帮助,并且与 Rust 的标准内存安全功能相比也没有提供任何额外的好处。您似乎在提到我不知道的另一种“堆栈保护”。 - Sven Marnach
1
嵌套向量与一维数组之间并不总是存在性能差异。我很惊讶!我编写了一个光线追踪器,它存储了2D像素网格。基准测试显示,在将2D网格存储在一维数组和vec-inside-vec中之间没有任何区别。 - Adam

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