我正在对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成正比的内存。