【发布时间】:2019-05-28 18:47:54
【问题描述】:
我正在运行一个大型蒙特卡罗模拟,我发现子设置/搜索我的数据是我的代码中最慢的部分。为了测试一些替代方案,我使用数据框、data.table 和矩阵对性能进行了基准测试。 这是基准代码:
library(data.table)
#install.packages('profvis')
library(profvis)
x.df = data.frame(a=sample(1:10,10000,replace=T), b=sample(1:10,10000,replace=T)) # set up a dataframe
x.dt = as.data.table(x.df) # a data.table
setkey(x.dt,a) # set key for faster searches
x.mat = as.matrix(x.df) # a matrix
profvis({
for (i in 1:10000) {
# test simple subsetting
xsubset.mat = x.mat[100:200,2]
xsubset.df = x.df[100:200,2]
xsubset.dt = x.dt[100:200,2]
# test search preformance
xsearch.mat = x.mat[which(x.df$a==10),2]
xsearch.df = x.df[which(x.df$a==10),2]
xsearch.dt = x.dt[.(10),2]
}
})
这是我的结果: 说真的,我喜欢 data.table 的紧凑语法,我想知道是否可以做些什么来提高它的性能。根据创作者的说法,它应该是超快的。是不是我用错了?
【问题讨论】:
-
考虑使用并行包进行蒙特卡罗模拟,在多核上运行代码
-
我可以理解较慢的子集,因为
[i, j]可以根据表达式做很多事情,初始检查肯定会有开销。较慢的搜索确实让我觉得奇怪。 -
如果您的 x.dt 在这么多次迭代中是相同的,并且查找/搜索是针对像 a 这样的整数,则只需预先计算子集并将它们存储在列表中。
bs = split(x.dt$b, x.dt$a)并根据需要访问bs[[1]]。
标签: r performance data.table subset benchmarking