You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何给指针赋值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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:02:44