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

在R中正确使用microbenchmark函数执行基准测试的技术问询

关于R中microbenchmark函数使用的正确性疑问

背景与现有代码实现

我正在学习如何在R中使用microbenchmark函数,为此模拟了不同规模的随机数据集:

# 加载所需包
library(lubridate)
library(microbenchmark)
library(forecast)

my_list = list()
index =  c(100, 1000, 10000, 50000, 100000, 250000, 500000, 750000, 1000000)

for (i in 1:length(index))
{
  my_data_i = data.frame(dates = sample(seq(as.Date('2010/01/01'), as.Date('2023/01/01'), by="day"), replace = TRUE, index[i]), visits = 1)
  my_list[[i]] = my_data_i
}

随后定义了需要在每个数据集上重复执行的函数:

my_function = function(){
  # 按周聚合数据
  my_data_i_weekly <- aggregate(my_data_i$visits, list(week = week(my_data_i$dates), year = year(my_data_i$dates)), sum)

  # 转换为时间序列
  my_data_i_ts <- ts(my_data_i_weekly$x, start = c(min(my_data_i_weekly$week), min(my_data_i_weekly$year)), frequency = 52)

  # 使用auto.arima拟合ARIMA模型
  my_data_i_arima <- auto.arima(my_data_i_ts)
}

过去我会手动计时每次迭代:

results = list()
for (i in length(index))
{
    start.time_i <- Sys.time()
    my_data_i = my_list[[i]]
    print(replicate(n = 100, my_function()))
    end.time_i <- Sys.time()
    time.taken_i <- end.time_i - start.time_i
    results[[i]] = time.taken_i
}

现在尝试用microbenchmark函数完成计时:

my_list2 = list()

for (i in 1:length(index))
{
  my_data_i = my_list[[i]]
  res_i = microbenchmark(my_function(), times = 100)
  print(res_i)
  my_list2[[i]] = res_i
}

需求与疑问

我的核心需求是:

  • 在my_list[[1]]上运行my_function()100次并记录耗时
  • 在my_list[[2]]上运行my_function()100次并记录耗时
  • 以此类推,覆盖所有数据集

请问当前基于microbenchmark的实现方式是否正确?

另外,未来我希望绘制性能对比图:横轴为数据集规模,纵轴为运行耗时,用不同颜色的折线代表不同计算机的测试结果(类似一条红线、一条绿线的对比折线图)。


回答

你的当前代码在特定环境下可以运行,但存在明显的不规范问题,依赖全局变量会导致代码健壮性不足:

  1. 核心问题:函数依赖全局变量
    my_function直接引用了全局环境中的my_data_i,虽然在循环中你每次会给my_data_i赋值,但这种写法容易引发意外错误(比如其他代码修改了全局的my_data_i),不符合R的函数式编程规范。

  2. 正确的实现方式
    修改my_function,让它接受数据作为参数,避免依赖全局变量:

my_function <- function(data){
  # 按周聚合数据
  data_weekly <- aggregate(data$visits, list(week = week(data$dates), year = year(data$dates)), sum)
  # 转换为时间序列
  data_ts <- ts(data_weekly$x, start = c(min(data_weekly$week), min(data_weekly$year)), frequency = 52)
  # 使用auto.arima拟合ARIMA模型
  data_arima <- auto.arima(data_ts)
}

然后修改循环中的microbenchmark调用,传入对应数据集:

my_list2 = list()

for (i in 1:length(index)){
  current_data <- my_list[[i]]
  res_i <- microbenchmark(my_function(current_data), times = 100)
  print(res_i)
  my_list2[[i]] <- res_i
}

这种写法更清晰、健壮,也便于后续维护和扩展。

  1. 关于性能绘图的建议
    收集完my_list2中的结果后,可以提取每个数据集对应的耗时统计(比如均值、中位数),整理成包含「数据集规模」「不同计算机耗时」的数据框,之后使用ggplot2包即可绘制对比折线图,示例代码框架:
library(ggplot2)
# 假设整理后的数据集名为perf_data
ggplot(perf_data, aes(x = 数据集规模)) +
  geom_line(aes(y = 计算机1耗时均值, color = "计算机1")) +
  geom_line(aes(y = 计算机2耗时均值, color = "计算机2")) +
  labs(x = "数据集规模", y = "平均耗时(秒)", color = "设备") +
  theme_minimal()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:44:59