我有一个超过10亿个观测值的大数据,我需要执行一些很慢的字符串操作。
我的代码就像这样简单:
DT[, var := some_function(var2)]
如果我没弄错的话,data.table
使用多线程,当它被by
调用时,我试图利用这个并行化这个操作。为此,我可以创建一个临时的grouper变量,如
DT[, grouper := .I %/% 100]
和
DT[, var := some_function(var2), by = grouper]
我用一个小样本数据进行了一些基准测试,但令人惊讶的是,我没有看到性能的提高。所以我的问题是:
data.table
使用多线程的时候使用by
?- 如果是,是否有启用/禁用多线程的条件?
- 是否有一种方法使用户可以"强制执行"?
data.table
在这里使用多线程?
仅供参考,当我导入数据时,我看到一半的内核启用了多线程。所以我想这里没有openMP问题。
我从数据中得到了data.table
开发者的答案。表github。
总结:
-
找到组
by
变量本身是并行,但更重要的是, -
如果
j
上的函数是泛型(用户定义函数),则没有并行化。 -
如果函数(gforce)优化(表达式j中只包含函数
min
,max
,mean
,median
,var
,sd
,sum
,prod
,first
,last
,head
,tail
),则对j
的操作是并行的
因此,如果j
上的函数是通用的,建议手动进行并行操作,但它可能并不总是保证速度增益。参考
解决方案= = = =
在我的例子中,当我直接使用DT[, var := some_function(var2)]
时,即使我的服务器有1TB的ram,而数据占用200GB的内存,我遇到了向量内存耗尽。
我使用split(DT, by='grouper')
将我的data.table
分成块,并使用doFuture
foreach
%dopar%
来完成这项工作。这是相当快的。