关于data.table 1.9.2中的GForce

Big*_*hao 14 r data.table

我不知道如何在data.table 1.9.2中充分利用GForce

新的优化:GForce.不是对数据进行分组,而是将组位置传递到sum和mean(gsum和gmean)的分组版本,然后计算单个顺序传递列中所有组的结果以获得缓存效率.此外,由于g*函数只被调用一次,我们不需要找到加速调用sum的方法或重复每个组的平均值.`

提交以下代码时

DT <- data.table(A=c(NA,NA,1:3), B=c("a",NA,letters[1:3]))
DT[,sum(A,na.rm=TRUE),by= B]
Run Code Online (Sandbox Code Playgroud)

我懂了

    B V1
1:  a  1
2: NA  0
3:  b  2
4:  c  3

DT[,sum(A,na.rm=FALSE),by= B]我尝试时,我得到了

    B  V1
1:  a  NA
2:  NA NA
3:  b  2
4:  c  3

这个结果是否解释了GForce的作用,添加na.rm = TRUE/FALSE选项?

非常感谢!

Mat*_*wle 28

这跟无关na.rm.你展示的内容也很好.但是,我明白为什么你可能会想到这一点.以下是同一个新闻项目的其余部分:

Examples where GForce applies now :
    DT[,sum(x,na.rm=),by=...]                       # yes
    DT[,list(sum(x,na.rm=),mean(y,na.rm=)),by=...]  # yes
    DT[,lapply(.SD,sum,na.rm=),by=...]              # yes
    DT[,list(sum(x),min(y)),by=...]                 # no. gmin not yet available
GForce is a level 2 optimization. To turn it off: options(datatable.optimize=1)
Reminder: to see the optimizations and other info, set verbose=TRUE
Run Code Online (Sandbox Code Playgroud)

您无需做任何有益的事情,这是一种自动优化.

这是一个有5亿行和4列(13GB)的例子.首先创建并说明数据:

$ R
R version 3.0.2 (2013-09-25) -- "Frisbee Sailing"
Copyright (C) 2013 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

> require(data.table)
Loading required package: data.table
data.table 1.9.2  For help type: help("data.table")

> DT = data.table( grp = sample(1e6,5e8,replace=TRUE), 
                   a = rnorm(1e6),
                   b = rnorm(1e6),
                   c = rnorm(1e6))
> tables()
     NAME        NROW    MB COLS      KEY
[1,] DT   500,000,000 13352 grp,a,b,c    
Total: 13,352MB
> print(DT)
          grp          a            b          c
1e+00: 695059 -1.4055192  1.587540028  1.7104991
2e+00: 915263 -0.8239298 -0.513575696 -0.3429516
3e+00: 139937 -0.2202024  0.971816721  1.0597421
4e+00: 651525  1.0026858 -1.157824780  0.3100616
5e+00: 438180  1.1074729 -2.513939427  0.8357155
   ---                                          
5e+08: 705823 -1.4773420  0.004369457 -0.2867529
5e+08: 716694 -0.6826147 -0.357086020 -0.4044164
5e+08: 217509  0.4939808 -0.012797093 -1.1084564
5e+08: 501760  1.7081212 -1.772721799 -0.7119432
5e+08: 765653 -1.1141456 -1.569578263  0.4947304
Run Code Online (Sandbox Code Playgroud)

现在花时间进行GForce优化(默认).请注意,这里没有setkey第一个.当你想以许多不同的方式进行分组时,这就是所谓的冷酷临时性的常见做法.

> system.time(ans1 <- DT[, lapply(.SD,sum), by=grp])
   user  system elapsed 
 47.520   5.651  53.173 
> system.time(ans1 <- DT[, lapply(.SD,sum), by=grp])
   user  system elapsed 
 47.372   5.676  53.049      # immediate repeat to confirm timing
Run Code Online (Sandbox Code Playgroud)

现在关闭GForce优化(根据NEWS项目)以查看它产生的差异:

> options(datatable.optimize=1)

> system.time(ans2 <- DT[, lapply(.SD,sum), by=grp])
   user  system elapsed 
 97.274   3.383 100.659 
> system.time(ans2 <- DT[, lapply(.SD,sum), by=grp])
   user  system elapsed 
 97.199   3.423 100.624      # immediate repeat to confirm timing
Run Code Online (Sandbox Code Playgroud)

最后,确认结果是一样的:

> identical(ans1,ans2)
[1] TRUE
> print(ans1)
            grp          a          b          c
      1: 695059  16.791281  13.269647 -10.663118
      2: 915263  43.312584 -33.587933   4.490842
      3: 139937   3.967393 -10.386636  -3.766019
      4: 651525  -4.152362   9.339594   7.740136
      5: 438180   4.725874  26.328877   9.063309
     ---                                        
 999996: 372601  -2.087248 -19.936420  21.172860
 999997:  13912  18.414226  -1.744378  -7.951381
 999998: 150074  -4.031619   8.433173 -22.041731
 999999: 385718  11.527876   6.807802   7.405016
1000000: 906246 -13.857315 -23.702011   6.605254
Run Code Online (Sandbox Code Playgroud)

请注意,data.table根据组首次出现的时间保留组的顺序.要订购分组结果,请使用keyby=而不是by=.

重新打开GForce优化(默认是Inf从所有优化中受益):

> options(datatable.optimize=Inf)
Run Code Online (Sandbox Code Playgroud)

另外:如果您不熟悉lapply(.SD,...)语法,它只是一种逐列应用函数的方法.例如,这两行是等价的:

 DT[, lapply(.SD,sum), by=grp]               # (1)
 DT[, list(sum(a),sum(b),sum(c)), by=grp]    # (2) exactly the same
Run Code Online (Sandbox Code Playgroud)

第一个(1)更有用,因为您有更多列,特别是与.SDcols控制哪个列子集以应用函数相结合.

NEWS项目只是试图表明使用这些语法中的哪一个无关紧要,或者您是否通过na.rm,GForce优化仍将应用.它说,你可以混合sum()mean()在一个调用(语法(2)允许的话),但只要你做别的事情(像min()),那么苹果牛不会因为踢min尚未完成; 只meansum有目前苹果牛的优化.您可以使用verbose=TRUE以查看是否正在应用GForce.

用于此时间的机器的详细信息:

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    8
Core(s) per socket:    1
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 62
Stepping:              4
CPU MHz:               2494.022
BogoMIPS:              4988.04
Hypervisor vendor:     Xen
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              25600K
NUMA node0 CPU(s):     0-7
Run Code Online (Sandbox Code Playgroud)