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

多排除条件下Fast data.table子集化的性能优化问询

优化data.table多键排除操作的性能瓶颈

我在编写一段需多次迭代的代码,通过profvis定位到一处性能瓶颈:outcomes_dt[outcome_1 != exclude & outcome_2 != exclude & outcome_3 != exclude],该操作速度比其他代码慢约100倍。此操作针对已按outcome_1、outcome_2、outcome_3建键的大型data.table,目的是从所有潜在观测中排除指定观测。

可复现代码

exp_keys <- c(letters,LETTERS,month.name)
outcomes_dt <- data.table(outcome_1 = rep(exp_keys, each = 64*64),outcome_2 = rep(rep(exp_keys, each = 64), 64),outcome_3 = rep(exp_keys,64*64), value = 1:(64*64))
setkeyv(outcomes_dt, c("outcome_1","outcome_2","outcome_3"))
exclude <- "a"
outcomes_dt[outcome_1 != exclude & outcome_2 != exclude & outcome_3 != exclude]

性能测试结果

我已用microbenchmark对多种方案进行性能测试:

测试代码

microbenchmark(
  "keyed" = outcomes_dt[data.table(exclude,exclude,exclude)], # 查找单行
  "keyed_exc" = outcomes_dt[!data.table(exclude,exclude,exclude)], # 排除单行
  "keyed_single" = outcomes_dt[data.table(exclude)], # 查找第一列所有匹配项
  "keyed_exc_single" = outcomes_dt[!data.table(exclude)], # 排除第一列所有匹配项
  "filtered_1" = outcomes_dt[outcome_1 != exclude & outcome_2 != exclude & outcome_3 != exclude], # 过滤方案1(性能瓶颈)
  "filtered_2" = outcomes_dt[!(outcome_1 == exclude | outcome_2 == exclude | outcome_3 == exclude)], # 替代过滤方案
  "chained" = outcomes_dt[outcome_1 != exclude][outcome_2 != exclude][outcome_3 != exclude], # 链式过滤
  "exclude_keys" = outcomes_dt[data.table(exp_keys[2:64])] # 预过滤键值
)

测试输出

Unit: milliseconds
             expr       min        lq       mean     median         uq      max neval
            keyed  2.201301  3.291002   4.347171   3.858901   4.978051  14.9554   100
        keyed_exc 22.536301 31.464652  43.713268  35.506901  51.614801 184.8499   100
     keyed_single  2.545301  3.599850   4.607506   4.216601   5.199201  10.9757   100
 keyed_exc_single 23.042200 30.461651  37.625179  34.187701  41.726401  80.6452   100
       filtered_1 30.460302 42.361101  58.039301  48.205951  68.223401 238.8149   100 # 能否优化?
       filtered_2 38.597800 45.118002  57.723060  52.782100  65.944351 181.1115   100 
          chained 69.779000 93.019601 114.897401 105.665200 123.846851 263.9510   100
     exclude_keys 27.473900 34.473251  43.897457  38.198352  46.258451 227.0823   100

我清楚这些方案并非完全等价,但希望找到类似keyed方法的更优提速方案,尤其是能利用已建键的方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:24:56