rust 初始化Vec的不同方法是否会< T>创建不同的内存布局?

eqqqjvef  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(105)
fn main() {
    let vec0 = vec![0; 10];

    let mut vec1 = vec![];
    for _ in 0..10 {
        vec1.push(0);
    }

    assert_eq!(vec0.len(), vec1.len());
}

字符串
在本例中,vec0vec1在使用index访问其项时是相同的。但是这两种初始化的方法会导致不同的内存布局吗?
更多背景:我正在构建一个(希望如此)缓存友好的容器(到目前为止是Vec<T>)来利用缓存局部性。通常在C++中,你可以分配一个具有动态长度(auto array = new DataType[length];)的新数组来强制紧凑的内存布局,但在Rust中,变量长度数组是不可能的。因此,我正在寻找一种构建Vec<T>的方法,它可以提高执行期间的缓存命中/未命中率。

r6l8ljro

r6l8ljro1#

正如@AleksanderKrauze所回答的那样,两者之间的唯一区别是最终容量和初始化时间,这是由于for循环中可能存在多次重新分配。但是,你可以在Rust中做一个与C++动态数组等效的操作:

let a = Box::from_iter (std::iter::repeat (0).take (length));

字符串
Playground

kcwpcxri

kcwpcxri2#

documentation
具有堆分配内容的连续可增长数组类型,写为Vec<T>
Rust中的std::vec::Vec<T>与C中的std::vector<T>几乎相同。它们都将数据存储在一个连续的元素数组中。在Rust中,这一点更加明显,因为Vec<T>实现了Deref<Target = [T]>。而所有的slices表示“进入连续序列的视图”。
在创建Vec的不同方法之间,数据在内存中的布局方式没有区别。唯一的区别可能是容量的大小,因为宏vec!将使用它的with_capacity方法创建向量,而当你推到一个向量时,你将不得不重新分配,由于摊销,你最终可能会得到不同的容量(使用宏也会更快,因为你不必做所有这些重新分配)。
通常在C
中,你可以分配一个具有动态长度(auto array = new DataType[length];)的新数组来强制紧凑的内存布局,但在Rust中,可变长度数组是根本不可能的。
这并不完全正确。在 * 标准库 * 中没有 stablesafe 方法来做这件事。但是,如果你想自己使用分配器,或者使用一些不稳定的特性(例如Box::new_uninit_slice),你可以创建完全相同的堆存储数组。虽然Vec可能会工作得很好。请记住使用with_capacity创建它。

相关问题