代码之家  ›  专栏  ›  技术社区  ›  JRR

分组是否在数据表1.12.0中并行?

  •  7
  • JRR  · 技术社区  · 7 年前

    data.table v1.12.0 我注意到以下几点:

    子集、排序和分组现在使用更多的并行性

    我测试了是否可以加快分组速度,但没有成功。我做了几个不同的测试,结果总是一样的。分组实际上是并行的吗?也许我没有正确使用线程选项?如你所见 data.table 已用 openmp 否则 setDTthread 打印一条消息,告诉用户不支持 并行算法 . 这里是我的一个测试的可复制示例。

    library(data.table)
    
    n = 5e6
    k = 1e4
    
    DT = data.table(x = runif(n), y = runif(n), grp = sample(1:k, n, TRUE))
    
    # Any function not too fast
    f = function(x,y) as.list(eigen(cov(cbind(x,y)), only.values = TRUE)$value)
    
    setDTthreads(1)
    getDTthreads()
    #> [1] 1
    
    system.time(DT[ , f(x,y), by = grp])
    #> utilisateur     système      écoulé 
    #>       3.365       0.008       3.374
    
    setDTthreads(0)
    getDTthreads(T)
    #> omp_get_max_threads() = 4
    #> omp_get_thread_limit() = 2147483647
    #> DTthreads = 0
    #> RestoreAfterFork = true
    #> [1] 4
    
    system.time(DT[ , f(x,y), by = grp])
    #> utilisateur     système      écoulé 
    #>       3.324       0.029       3.238
    

    于2019年1月27日由 reprex package

    2 回复  |  直到 7 年前
        1
  •  7
  •   Hugh    7 年前

    是的,分组在V1.12.0中是并行的

    你的基准有点像转移视线。你想要一杯吗 快速的 f(x, y)

    library(data.table)
      packageVersion("data.table")
    #> [1] '1.12.0'
    
    n = 5e6
    N <- n
    k = 1e4
    
    print(getDTthreads())
    #> [1] 12
    
    DT = data.table(x = rep_len(runif(n), N),
                    y = rep_len(runif(n), N),
                    grp = rep_len(sample(1:k, n, TRUE), N))
    bench::system_time(DT[, .(a = 1L), by = "grp"])
    #>   process      real 
    #> 250.000ms  72.029ms
    
    setDTthreads(1)
    
    bench::system_time(DT[, .(a = 1L), by = "grp"])
    #>   process      real 
    #> 125.000ms 126.385ms
    

    于2019-02-01由 reprex package (v0.2.1)

    也就是说,在并行情况下,我们的速度稍微快了一点,但只有大约50毫秒——与函数的3秒相比可以忽略不计。

    如果我们不考虑DT的大小,我们可以看到更显著的差异:

    library(data.table)
      packageVersion("data.table")
    #> [1] '1.12.0'
    
    n = 5e6
    N <- 1e9
    k = 1e4
    
    print(getDTthreads())
    #> [1] 12
    
    DT = data.table(x = rep_len(runif(n), N),
                    y = rep_len(runif(n), N),
                    grp = rep_len(sample(1:k, n, TRUE), N))
    bench::system_time(DT[, .(a = 1L), by = "grp"])
    #> process    real 
    #> 45.719s 14.485s
    
    setDTthreads(1)
    
    bench::system_time(DT[, .(a = 1L), by = "grp"])
    #> process    real 
    #> 24.859s 24.890s
    
    sessioninfo::session_info()
    #> - Session info ----------------------------------------------------------
    #>  setting  value                       
    #>  version  R version 3.5.2 (2018-12-20)
    #>  os       Windows 10 x64              
    #>  system   x86_64, mingw32             
    #>  ui       RTerm                       
    #>  language (EN)                        
    #>  collate  English_Australia.1252      
    #>  ctype    English_Australia.1252      
    #>  tz       Australia/Sydney            
    #>  date     2019-02-01                  
    #> 
    

    于2019-02-01由 (v0.2.1)

        2
  •  1
  •   JRR    7 年前

    此处的答案未经任何权威机构(例如 data.table 数据表 github存储库中的问题。

    #3042 sum mean

    library(data.table)
    n = 1e7 ; k = 1e5
    DT = data.table(x = runif(n), y = runif(n), grp = sample(1:k, n, TRUE))
    
    setDTthreads(1)
    system.time(DT[ , mean(x), by = grp]) #> 0.8 s
    setDTthreads(0)
    system.time(DT[ , mean(x), by = grp]) #> 0.4 s
    

    但是马特·道尔在同一期中 #3042 写的:

    而且 #3130 斯里奇写道

    这里值得注意的是,R函数本质上不是线程安全的,例如,它们不能通过RCPP传递给多线程C++代码。

    因此,用户定义函数的并行化似乎不是一项简单的任务,而且目前还没有实现

    推荐文章