Rust中两个空函数执行耗时差异的原因探究
问题
我在Rust中编写了两个空函数use_filter和use_retain,原本计划分别用于测试向量的retain方法和迭代器的filter方法。运行测试程序后,发现这两个空函数的执行耗时存在显著差异,这会导致后续添加业务逻辑后得出错误的执行时间结论。
测试代码如下:
use std::time::Instant; fn use_filter() { } fn use_retain() { } fn run_multiple(f: fn(), times: u64) { for _ in 0..times { f() } } fn main() { let iter_count: u32 = 1_000_000_000; let _start_1 = Instant::now(); run_multiple(use_filter, iter_count as u64); let duration = Instant::now() - _start_1; println!("Use Filter duration: {:?}", duration / iter_count); let _start_2 = Instant::now(); run_multiple(use_retain, iter_count as u64); let duration = Instant::now() - _start_2; println!("Use Retain duration: {:?}", duration / iter_count); }
预期输出
Use Filter duration: xns Use Retain duration: xns
其中x值相同,因两个函数均为空函数
实际输出
Use Filter duration: 8ns Use Retain duration: 10ns
原因分析
- 编译器优化的细微差异:Rust编译器在处理空函数时,针对不同函数的优化策略可能存在区别。因为你将函数作为指针传递给
run_multiple,编译器对两个空函数的内联决策、代码消除行为可能不一致,导致生成的机器码调用开销有细微差别。空函数本身没有实际逻辑,这种优化层面的差异会直接体现在执行耗时上。 - CPU执行环境的非确定性:第一个函数执行时,CPU处于冷启动状态,缓存、分支预测器都未预热;第二个函数执行时,CPU已经处于热状态,但指令流水线的填充、分支预测历史的差异,也会导致单次调用的耗时出现波动。10亿次的迭代会把这种微小的单次差异放大,呈现出可观测的耗时区别。
- 空函数基准测试无参考价值:空函数的执行耗时完全由编译器优化和调用开销主导,和你后续要测试的
filter、retain的实际业务逻辑开销没有关联。这种测试无法反映真实场景下的性能差异,反而会因为优化和环境因素干扰后续结论。
内容的提问来源于stack exchange,提问作者Brian Obot
相关产品推荐
相关产品推荐

