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

重复子集化大型dataframe/data.table时极端耗时现象的原因探究

大型DataFrame/Data.table子集化的极端耗时现象分析

现象描述

在重复子集化一个约8GB的大型数据集(200万行×500列)时,观察到计算耗时波动极大:最大值远高于中位数,部分场景下差值甚至达一个数量级。

数据生成与基准测试代码

首先生成测试数据(修正原代码索引定义顺序的笔误):

set.seed(100)
tmp_df <- data.frame(lapply(1:500, function(i) runif(2e6)))
# 先定义子集索引,再生成小表子集
tmp_ind <- sample(seq_len(nrow(tmp_df)), 8000) 
tmp_df_2 <- tmp_df[tmp_ind, ]

对两种返回相同8000行子集的操作进行基准测试:

tmp_mbm_obj_1 <- microbenchmark(fn = tmp_df[tmp_ind, ], times = 500)
tmp_mbm_obj_2 <- microbenchmark(fn = tmp_df_2[seq_len(nrow(tmp_df_2)), ], times = 500)

DataFrame基准测试结果(单位:毫秒)

表达式最小值下四分位数均值中位数上四分位数最大值重复次数
tmp_mbm_obj_169.04577.891286.9264781.3762588.7259216.2269500
tmp_mbm_obj_222.865526.7984533.0805728.66631.0665289.3311500

可以看到,两种操作的最大值均远大于中位数,其中第二种操作的差值几乎达一个数量级。


Data.table下的现象

将数据转换为data.table后,均值耗时有所降低,但最大值的波动幅度更为明显:

测试代码

setDT(tmp_df)
setDT(tmp_df_2)
tmp_mbm_obj_dt_1 <- microbenchmark(fn = tmp_df[tmp_ind, ], times = 500)
tmp_mbm_obj_dt_2 <- microbenchmark(fn = tmp_df_2[seq_len(nrow(tmp_df_2)), ], times = 500)

Data.table基准测试结果(单位:毫秒)

表达式最小值下四分位数均值中位数上四分位数最大值重复次数
tmp_mbm_obj_dt_138.141441.5936550.3606842.668944.5913847.2804500
tmp_mbm_obj_dt_225.874327.5692534.4942127.9494528.7855793.3998500

运行环境

  • CPU:Xeon E5-1620 v4
  • R版本:4.2.0 (2022-04-22 ucrt)
  • 平台:x86_64-w64-mingw32/x64 (64-bit)
  • 内存:总内存63.924 GiB,空闲内存45.379 GiB

原因分析

1. 内存缓存与页面调度

  • 子集化大表时,随机抽取的行数据分布分散,CPU缓存命中率低,首次操作需要从内存中读取大量非连续数据块;而小表的连续数据更容易被缓存,平均耗时更低。
  • 即使空闲内存充足,操作系统的后台进程、内存碎片整理或临时页面调度操作,会导致部分运行时缓存失效,触发较慢的内存读取,从而产生极端耗时的样本。

2. data.table的底层机制

data.table采用了更高效的内存布局和延迟加载优化,均值耗时更低,但它的内存复用策略在遇到系统临时回收缓存页时,需要重新初始化数据结构或读取数据,导致单次操作耗时大幅上升,表现为更大的最大值波动。

3. 操作系统与R内存管理

  • Windows系统的mingw编译版R,对大内存数据的处理存在额外开销,当操作涉及大量内存块复制或寻址时,偶尔会触发系统级的内存整理操作,导致耗时突增。
  • 尽管microbenchmark默认会在每次运行前触发垃圾回收(GC),但仍可能存在未被捕获的GC操作,或系统后台GC抢占资源,导致部分运行耗时异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:52:35