R中的基准测试“样本”函数

pas*_*y51 11 random r

我正在对sampleR 中的函数进行基准测试并将其与它进行比较igraph:sample_seq并遇到了一个奇怪的结果。

当我运行类似的东西时:

library(microbenchmark)
library(igraph)
set.seed(1234)
N <- 55^4
M <- 500
(mbm <- microbenchmark(v1 = {sample(N,M)}, 
                       v2 = {igraph::sample_seq(1,N,M)}, times=50))
Run Code Online (Sandbox Code Playgroud)

我得到这样的结果:

Unit: microseconds
 expr       min        lq        mean     median        uq       max neval
   v1 21551.475 22655.996 26966.22166 23748.2555 28340.974 47566.237    50
   v2    32.873    37.952    82.85238    81.7675    96.141   358.277    50
Run Code Online (Sandbox Code Playgroud)

但是当我跑步时,例如,

set.seed(1234)
N <- 100^4
M <- 500
(mbm <- microbenchmark(v1 = {sample(N,M)}, 
                      v2 = {igraph::sample_seq(1,N,M)}, times=50))
Run Code Online (Sandbox Code Playgroud)

我得到了更快的结果sample

Unit: microseconds
 expr    min     lq     mean  median     uq     max neval
   v1 52.165 55.636 64.70412 58.2395 78.636  88.120    50
   v2 39.174 43.504 62.09600 53.5715 73.253 176.419    50
Run Code Online (Sandbox Code Playgroud)

似乎什么时候N是 10 的幂(或其他一些特殊数字?),sample比其他N不是 10 的幂的小得多。这是预期的行为还是我错过了什么?

H 1*_*H 1 10

sample()或者更确切地说sample.int(),当满足某些条件时,默认情况下使用散列算法,其中一个是 n > 1e7。

如果在没有散列的情况下重新运行第二个基准测试,您会发现它也比 igraph 函数慢得多。

set.seed(1234)
N2 <- 100^4
M <- 500
(mbm <- microbenchmark(v1 = {sample.int(N2,M, useHash = FALSE)}, 
                       v2 = {igraph::sample_seq(1,N2,M)}, times=50))

Unit: microseconds
 expr        min         lq         mean     median         uq       max neval cld
   v1 144297.936 150368.649 167224.95664 154283.077 157832.520 407710.78    50   b
   v2     61.218     65.392     92.35544     87.885    118.262    148.87    50  a 
Run Code Online (Sandbox Code Playgroud)

useHash论据的文档中:

逻辑指示是否应使用算法的哈希版本。只能用于replace = FALSE, prob = NULL, and size <= n/2,并且真的应该用于大n,因为useHash=FALSE会使用与n成正比的内存。