Benchmarking de la fonction «échantillon» dans R

11

J'étalonnais la samplefonction dans R et je la comparais avec igraph:sample_sequn résultat étrange.

Quand je lance quelque chose comme:

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))

J'obtiens un résultat comme celui-ci:

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

Mais quand je cours, par exemple,

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

J'obtiens un résultat beaucoup plus rapide pour 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

Il semble que quand Nest une puissance de 10 (ou un autre nombre spécial?), sampleEst beaucoup plus rapide que les autres plus petits Nqui ne sont pas des puissances de 10. Est-ce le comportement attendu ou est-ce que je manque quelque chose?

passant51
la source

Réponses:

10

sample()ou plutôt sample.int()par défaut utilise un algorithme de hachage lorsque certaines conditions sont remplies, l'une étant que n> 1e7.

Si la deuxième référence est réexécutée sans hachage, vous verrez qu'elle est également beaucoup plus lente que la fonction 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 

De la documentation de l' useHashargument:

logique indiquant si la version de hachage de l'algorithme doit être utilisée. Ne peut être utilisé que pour replace = FALSE, prob = NULL et size <= n / 2, et doit vraiment être utilisé pour les grands n, car useHash = FALSE utilisera la mémoire proportionnelle à n.

H 1
la source
Intéressant! Cela semble être ça.
passerby51
Maintenant, je me demande s'il est possible de comparer la quantité de mémoire utilisée par le "sample.int" haché par rapport à igraph :: sample_seq (?)
passerby51