在一个语句中,多个data.table赋值是否具有性能优势?

时间:2015-12-09 15:33:24

标签: r performance data.table variable-assignment

data.table中,以下内容具有相同的结果:

dt1 <- data.table(iris)
dt1[, Long.Petal := Petal.Length > mean(Petal.Length)]
dt1[, Wide.Petal := Petal.Width > mean(Petal.Width)]

dt2 <- data.table(iris)
dt2[, `:=`(
  Long.Petal = Petal.Length > mean(Petal.Length),
  Wide.Petal = Petal.Width > mean(Petal.Width)
)]

使用大型数据集时,后一种形式是否具有性能优势(在内存或运行时或两者方面)?或者是最小的开销,它只是风格和可读性的问题?

2 个答案:

答案 0 :(得分:4)

需要考虑的事项是:a)对[.data.table的调用,以及b)在[.data.table中运行代码。

对于几个电话,它不应该真正影响。但是如果你正在做这个或者1000多次(例如,使用for-loop),那么它可能性能较差......主要是由于调度的时间{{1 }}。在这种情况下,只要没有分组,[.data.table就是一个更好的选择。

在任何情况下,这些内容都很容易在您的数据集上进行基准测试。调用set()应该知道所花费的时间以及花费大部分时间。

答案 1 :(得分:4)

我很惊讶在以下示例中实际上存在不可忽略的性能差异。而且它不赞成合并后的任务:

set.seed(42)
dt1 <- data.table(x = rnorm(1e7))
dt2 <- copy(dt1)

library(microbenchmark)

microbenchmark({dt1[, y := x < 0]; dt1[, z := x > 0]},
               dt2[,`:=`(
                 y = x < 0,
                 z = x > 0
               )])
#Unit: milliseconds
#                                                   expr      min       lq     mean   median       uq      max neval cld
#{     dt1[, `:=`(y, x < 0)]     dt1[, `:=`(z, x > 0)] } 122.6285 124.0237 143.3914 125.2057 146.0050 305.3609   100  a 
#                      dt2[, `:=`(y = x < 0, z = x > 0)] 153.2545 156.5720 208.5669 178.9714 301.8305 359.2821   100   b

all.equal(dt1, dt2)
#[1] TRUE