检查微基准测试结果失败,data.table通过引用更改

时间:2016-08-02 09:34:07

标签: r data.table microbenchmark

在SO上有一些答案,其中时间与进行比较没有检查结果。但是,我更喜欢看表达式是否正确。

microbenchmark包使用check参数支持此功能。不幸的是,对于通过引用更改data.table 的表达式,检查失败,即检查无法识别结果不同。

案例1:data.table表达式,其中检查按预期工作

library(data.table)
library(microbenchmark)

# minimal data.table 1 col, 3 rows
dt <- data.table(x = c(1, 1, 10))

# define check function as in example section of help(microbenchmark)
my_check <- function(values) {
  all(sapply(values[-1], function(x) identical(values[[1]], x)))
}

基准案例旨在返回不同的结果。因此,

microbenchmark(
  f1 = dt[, mean(x)],
  f2 = dt[, median(x)],
  check = my_check
)

按预期返回错误消息:

  

错误:输入表达式不等效。

案例2:检查失败的data.table表达式

现在,修改表达式以通过引用更改dt。请注意,使用相同的检查功能。

microbenchmark(
  f1 = dt[, y := mean(x)],
  f2 = dt[, y := median(x)],
  check = my_check
)

现在返回

 expr     min      lq     mean   median       uq     max neval cld
   f1 576.947 625.174 642.9820 640.7110 661.1870 732.391   100  a 
   f2 602.022 658.384 684.7076 678.9975 694.0825 978.600   100   b

因此,尽管两个表达式 不同,但结果检查失败了。 (时间是无关紧要的。)

我了解检查确定失败,因为dt已被引用更改。因此,在比较每个表达式的结果时,始终在最后一次更改的状态中引用相同的对象。

问题

如何修改检查功能和/或表达式,以便即使在通过引用更改data.table的情况下,检查也能可靠地检测到不同的结果?

1 个答案:

答案 0 :(得分:4)

最简单的方法是使用public static long bytesToLong(byte[] bytes) { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.put(bytes, 0, bytes.length); buffer.flip();//need flip return buffer.getLong(); } public static byte[] longToBytes(long x) { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(0, x); return buffer.array(); }

copy()

在混合中添加microbenchmark( f1 = copy(dt)[, y := mean(x)], f2 = copy(dt)[, y := median(x)], check = my_check, times=1L ) # Error: Input expressions are not equivalent. 可以了解复制所花费的时间(如果需要,可以总是从copy(dt)f1的运行时中减去该值。 / p>

f2