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

如何从bench::mark的memory列获取更多内存基准测试详情

解决bench::mark内存列详情查看与内存优化建议

一、获取内存列的详细信息

bench::mark返回结果中的memory列是Rprofmem类型对象,直接打印仅显示摘要。要查看完整内存分配记录,将其转换为数据框即可:

# 先保存基准测试结果
bench_res <- bench::mark(
  iterations = 4,
  check = FALSE,
  "dplyr" = test_data %>% mutate(mean = rowMeans(.[, ColNum:length(.)], na.rm=T), 
                                 var = row_sample_variance(.[, ColNum:length(.)], na.rm=T), 
                                 SD = sqrt(var), 
                                 "-95%" = mean -(1.96*SD), 
                                 "+95%" = mean +(1.96*SD)), 
  "Indvidual" = {
    rowMeans(test_data[, ColNum:length(test_data)], na.rm=T)
    row_sample_variance(test_data[, ColNum:length(test_data)], na.rm=T)
    sqrt(row_sample_variance(test_data[, ColNum:length(test_data)], na.rm=T)) 
    rowMeans(test_data[, ColNum:length(test_data)], na.rm=T) -(1.96*sqrt(row_sample_variance(test_data[, ColNum:length(test_data)], na.rm=T)))
    rowMeans(test_data[, ColNum:length(test_data)], na.rm=T) +(1.96*sqrt(row_sample_variance(test_data[, ColNum:length(test_data)], na.rm=T)))
  }, 
  "full dplyr" = test_data %>%  mutate(mean = rowMeans(.[, ColNum:length(.)], na.rm=T), 
                                       var = row_sample_variance(.[, ColNum:length(.)], na.rm=T), 
                                       SD = sqrt(row_sample_variance(.[, ColNum:length(.)], na.rm=T)), 
                                       "-95%" = rowMeans(.[, ColNum:length(.)], na.rm=T) -(1.96*sqrt(row_sample_variance(.[, ColNum:length(.)], na.rm=T))), 
                                       "+95%" = rowMeans(.[, ColNum:length(.)], na.rm=T) +(1.96*sqrt(row_sample_variance(.[, ColNum:length(.)], na.rm=T))))
)

# 查看所有测试组的内存详情
lapply(bench_res$memory, as.data.frame)

# 单独查看某一组(比如dplyr)的内存分配
as.data.frame(bench_res$memory[["dplyr"]])

转换后的数据框包含三列核心信息:

  • what:内存分配的对象类型(如矩阵、向量)
  • bytes:分配的内存字节数
  • trace:触发内存分配的调用栈,可定位高内存消耗的代码段

二、针对千万行数据集的内存优化建议

你的测试场景是千万行30列数据,当前代码存在重复计算和不必要的临时对象,这会大幅增加内存占用,以下是关键优化点:

1. 避免重复计算

当前"Indvidual"和"full dplyr"组重复调用rowMeans和row_sample_variance多次,每次调用都会生成临时对象。应复用中间结果减少内存开销:

# dplyr优化版:仅计算一次均值和方差
test_data %>% 
  mutate(mean = rowMeans(.[, ColNum:length(.)], na.rm=T), 
         var = row_sample_variance(.[, ColNum:length(.)], na.rm=T)) %>%
  mutate(SD = sqrt(var), 
         "-95%" = mean - 1.96*SD, 
         "+95%" = mean + 1.96*SD)

2. 优化方差计算函数

原row_sample_variance中x - rowMeans(x)会生成与输入同尺寸的临时矩阵,对千万行数据来说内存占用极高。改用方差的代数等价公式,避免大临时对象:

row_sample_variance_opt <- function(x, na.rm = FALSE) {
  n <- if (na.rm) rowSums(!is.na(x)) else ncol(x)
  # 处理n<=1的情况,避免除以0
  n[n <= 1] <- 2
  sum_x <- rowSums(x, na.rm = na.rm)
  sum_x2 <- rowSums(x^2, na.rm = na.rm)
  (n * sum_x2 - sum_x^2) / (n * (n - 1))
}

该版本仅计算行和与行平方和,内存占用远低于原函数。

3. 加入data.table对比

data.table在大数据集的内存控制和计算效率上表现更优,建议加入测试组:

library(data.table)
test_dt <- as.data.table(test_data)

bench::mark(
  iterations = 4,
  check = FALSE,
  "data.table" = test_dt[, `:=`(
    mean = rowMeans(.SD, na.rm = TRUE),
    var = row_sample_variance_opt(.SD, na.rm = TRUE)
  ), .SDcols = ColNum:ncol(test_dt)][, `:=`(
    SD = sqrt(var),
    "-95%" = mean - 1.96*SD,
    "+95%" = mean + 1.96*SD
  )]
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:25:01