为何给指针赋值None时,不同类型的操作耗时存在差异?
为何给
Option<V>指针赋值None时不同类型耗时有差异? 测试代码
use std::alloc::{alloc, Layout}; use std::time::Instant; const CAP : usize = 100000; struct Foo<V> { head: *mut Option<V> } impl<V> Foo<V> { pub fn new() -> Self { unsafe { let layout = Layout::array::<Option<V>>(CAP).unwrap(); let ptr = alloc(layout); Self { head: ptr.cast() } } } pub fn measure(&self) { let start = Instant::now(); for i in 0..CAP { unsafe { *self.head.add(i) = None; } } println!("spent: {:?}", start.elapsed()); } } fn main() { Foo::<bool>::new().measure(); Foo::<u64>::new().measure(); Foo::<[u8; 100]>::new().measure(); Foo::<[u8; 1000]>::new().measure(); }
运行输出
spent: 1.33425ms spent: 1.654208ms spent: 3.541ms spent: 17.383459ms
差异原因解析
核心在于不同类型对应的Option<V>内存大小不同,赋值None时的总写入数据量差异直接导致了耗时区别:
Option<bool>:Rust做了特殊空间优化,整个类型仅占1字节。因为bool只有0、1两个有效值,None可以用第三个状态标记,所以每次赋值None只需要写1字节内存。10万次操作总写入量仅100KB,耗时最短。Option<u64>:u64的所有64位取值都是有效数值,无法和None复用内存空间,因此Option<u64>需要额外的枚举判别式来区分变体。最终整个类型占16字节(8字节判别式+8字节u64值),每次赋值写16字节,总写入量1.6MB,耗时略高于bool版本。Option<[u8; 100]>:枚举判别式加上100字节的数组,整个类型占101字节,每次赋值写101字节,总写入量约9.6MB。此时数据量开始超出CPU缓存容量,需要频繁进行缓存交换,耗时进一步上升。Option<[u8; 1000]>:整个类型占1001字节,10万次操作总写入量接近95.4MB,远超常规CPU的L3缓存大小。大量写入操作需要直接和主存交互,内存带宽成为瓶颈,因此耗时大幅增加。
本质上,赋值None就是把Option<V>的完整字节表示写入内存,总写入数据量越大,耗时越高;当数据量超出CPU缓存时,主存访问的高延迟会被放大,导致耗时陡增。
内容的提问来源于stack exchange,提问作者yegor256
相关产品推荐
相关产品推荐

