dan*_*ptr 6 memory vector rust
我正在寻找分配一个小型结构的向量。
这需要 30 毫秒并线性增加:
let v = vec![[0, 0, 0, 0]; 1024 * 1024];
Run Code Online (Sandbox Code Playgroud)
这需要几十微秒:
let v = vec![0; 1024 * 1024];
Run Code Online (Sandbox Code Playgroud)
对于第一种情况是否有更有效的解决方案?我可以接受不安全的代码。
就一般情况而言,张方的回答是正确的。您询问的代码有点特殊:它可以使用alloc_zeroed,但它没有。正如 Stargateur 在问题评论中指出的那样,随着未来语言和库的改进,这两种情况都有可能利用这种加速。
这通常应该不是问题。一次初始化整个大向量可能不是您经常做的事情。大的分配通常是长期存在的,因此您不会在紧密的循环中创建和释放它们——初始化向量的成本很少会被支付。在诉诸 之前unsafe,我会检查一下我的算法并尝试理解为什么单个算法memset会造成如此多的麻烦。
但是,如果您碰巧知道全位为零是可接受的初始值,并且您alloc_zeroed绝对不能容忍速度下降,则可以通过调用和创建Vecusing来围绕标准库进行最终运行from_raw_parts。Vec::from_raw_parts是unsafe,所以您必须绝对确定分配的内存的大小和对齐方式是正确的。从 Rust 1.44 开始,您可以Layout::array轻松地做到这一点。这是一个例子:
pub fn make_vec() -> Vec<[i8; 4]> {
let layout = std::alloc::Layout::array::<[i8; 4]>(1_000_000).unwrap();
// I copied the following unsafe code from Stack Overflow without understanding
// it. I was advised not to do this, but I didn't listen. It's my fault.
unsafe {
Vec::from_raw_parts(
std::alloc::alloc_zeroed(layout) as *mut _,
1_000_000,
1_000_000,
)
}
}
Run Code Online (Sandbox Code Playgroud)
vec![0; 1024 * 1024]是一个特例。如果将其更改为vec![1; 1024 * 1024],您会发现性能急剧下降。
通常,对于非零元素e,vec![e; n]将克隆元素n次数,这是主要成本。对于等于 的元素0,还有其他系统方法来初始化内存,这种方法要快得多。
所以你的问题的答案是否定的。
| 归档时间: |
|
| 查看次数: |
886 次 |
| 最近记录: |