Rust中如何直接在堆上初始化Rc数组以避免memcpy操作?
直接在堆上初始化Rc包裹数组以规避memcpy的最简方案
问题背景
原代码通过Rc::new([42; 1024])创建Rc包裹的数组时,编译器会先在栈上生成完整数组,再通过memcpy复制到堆内存中,造成不必要的性能开销:
use std::rc::Rc; pub fn test() -> Rc<[usize; 1024]> { Rc::new([42; 1024]) }
最简解决方案
利用标准库的Rc::new_uninit()直接在堆上分配未初始化内存,然后原地填充元素,避免栈上数组的创建和复制:
use std::rc::Rc; use std::mem; pub fn test() -> Rc<[usize; 1024]> { // 在堆上分配未初始化的数组内存 let mut uninit_rc = Rc::new_uninit(); unsafe { // 获取堆内存的可变指针,直接填充所有元素为42 (*uninit_rc.as_mut_ptr()).fill(42); // 转换为已初始化的Rc(已完成所有元素初始化,操作安全) mem::transmute(uninit_rc) } }
方案说明
Rc::new_uninit():仅在堆上分配对应数组大小的内存,不做任何初始化操作,避免栈内存占用;- 原地填充:通过
as_mut_ptr()获取堆内存的可变指针,调用fill(42)直接在堆上完成所有元素的初始化,无需栈上复制; - 安全转换:
mem::transmute将未初始化的Rc<MaybeUninit<[usize; 1024]>>转换为Rc<[usize; 1024]>,由于我们已经完成了所有元素的初始化,这个操作是安全的。
如果不想编写unsafe代码,可以使用第三方库(如rc_box)提供的安全初始化API,但上述基于标准库的方案是最直接的实现方式。
内容的提问来源于stack exchange,提问作者David Frank
相关产品推荐
相关产品推荐

