为什么交叉(...)比数据表连接更快?

jlh*_*ard 7 r data.table

这个问题是由这个问题引起的.

考虑两个向量,ab两个数据表dt.a,dt.b如下所示:

a <- c(55, 1:25)
b <- c(55,30:40)

library(data.table)
dt.a <- data.table(x=a,key="x")
dt.b <- data.table(x=b,key="x")

intersect(a,b)
[1] 55
dt.a[dt.b,nomatch=0]
    x
1: 55
Run Code Online (Sandbox Code Playgroud)

目标是计算共同元素的数量.

我的问题是:为什么数据表加速比30X慢intersect(...)

system.time(for (i in 1:1000){intersect(a,b)})
   user  system elapsed 
   0.05    0.00    0.04 
system.time(for (i in 1:1000){dt.a[dt.b,nomatch=0]})
   user  system elapsed 
   1.68    0.00    1.69 
Run Code Online (Sandbox Code Playgroud)

mne*_*nel 14

当给出"大"问题时,data.table的力量会闪耀.开销[.data.table将使实际花费在二进制搜索组件上的时间相形见绌.

如果你给它一个"大"问题,那么data.table将扩展,你会看到差异.

# a "bigger" problem
a <- c(55, 1:25e6)
b <- c(55,30:40e6)

library(data.table)
dt.a <- data.table(x=a,key="x")
dt.b <- data.table(x=b,key="x")

library(microbenchmark)

microbenchmark(intersect(a,b), dt.a[dt.b, nomatch=0],times=5)
## Unit: seconds
##                     expr      min       lq   median       uq      max neval
##          intersect(a, b) 6.848245 6.897009 6.962055 7.052095 7.058509     5
##  dt.a[dt.b, nomatch = 0] 3.629062 3.654269 3.685051 3.721983 3.815155     5
Run Code Online (Sandbox Code Playgroud)

  • @jlhoward -25000不是特别大.`[.data.table`具有函数本身的开销以及与R中的s3方法调度相关的开销.我建议后者是最有贡献的. (2认同)