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

为何增大样本量时microbenchmark基准测试结果出现振荡?

基准测试耗时出现振荡现象的原因?

我用microbenchmark::microbenchmark()对两个函数做基准测试,还调整了输入样本量,结果发现性能耗时每次都有振荡。下面是一个简单while函数的测试情况:

fun <- function(n){
  i <- 1
  while (n > i) {
    i <- i + 1
  }
}

基准测试结果图

图中x轴是对数刻度的样本量n,y轴是中位数性能耗时。我本来以为函数运行时间会随n增大而增加,但实际不是这样,多次运行代码都得到相同的振荡结果。这是为什么?

生成数据和绘图的完整代码如下:

# 加载依赖包
library(magrittr)
library(ggplot2)
# 定义测试函数
fun <- function(n){
  i <- 1
  while (n > i) {
    i <- i + 1
  }
}
# 设置样本量
n <- c(10, 100, 1000, 10000, 100000, 1000000)
# 批量运行基准测试
results<- lapply(n, function(n_i){
  results_i <- microbenchmark::microbenchmark(fun(n= n_i),
                                          times= 1000)

  data.frame(n= n_i,
             time= summary(results_i)$median)
}) %>%
  do.call("rbind.data.frame", .)

# 绘制结果图
results %>%
  ggplot(data= ., mapping= aes(x= n, y= time)) +
  geom_smooth(se= FALSE) +
  geom_point() +
  scale_x_continuous(trans='log10') +
  theme_minimal()

原因分析

这种振荡现象主要和CPU分支预测机制以及微基准测试的噪声特性有关:

  • 分支预测的波动:你的while循环核心是n > i这个条件判断。CPU会通过分支预测提前预判循环是否继续,当迭代次数符合预测规律时(比如n为特定值),预测准确率极高,耗时大幅降低;一旦迭代次数打破预测模式,分支预测误判率上升,单次循环耗时会突然增加,最终表现为整体耗时的振荡。
  • 微基准测试的噪声放大:microbenchmark虽然能精确测量短耗时,但系统层面的干扰(进程调度、缓存命中/失效、CPU动态调频)在测试极短函数时会被放大。你的fun本身执行时间极短,哪怕是毫秒级的系统波动都会让结果出现明显振荡。
  • 小样本量的误差放大:当n较小时,循环迭代次数少,单次迭代的耗时占比更高,任何微小的执行差异都会被放大,导致结果波动更显著。

优化建议

  • 增加测试次数:将times参数调至更大值(比如times=10000),取多次测试的均值或中位数,能有效降低随机噪声的影响,让线性趋势更清晰。
  • 固定测试环境:关闭后台无关进程,避免资源竞争;如果是多核CPU,可将测试进程绑定到单个核心(Linux用taskset,Windows用Start-Process -Affinity),减少进程调度带来的干扰。
  • 调整函数逻辑:把while循环改为for循环,因为for循环的迭代次数提前确定,CPU分支预测的准确率更高,耗时随n增长会更接近线性:
    fun_for <- function(n){
      for(i in 1:n) {}
    }
    

内容的提问来源于stack exchange,提问作者LulY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:45:20