Benchmarking della funzione "campione" in R


11

Stavo confrontando la samplefunzione in R e confrontandola con igraph:sample_seqe ho riscontrato uno strano risultato.

Quando corro qualcosa del tipo:

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

Ottengo un risultato come questo:

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

Ma quando corro, per esempio,

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

Ottengo un risultato molto più veloce per 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

Sembra che quando Nè una potenza di 10 (o qualche altro numero speciale?), sampleÈ molto più veloce di altre più piccole Nche non sono potenze di 10. È questo comportamento previsto o mi sto perdendo qualcosa?

Risposte:


10

sample()o meglio sample.int()di default usa un algoritmo hash quando vengono soddisfatte determinate condizioni, una delle quali è n> 1e7.

Se il secondo benchmark viene eseguito nuovamente senza hashing, vedrai che è anche molto più lento rispetto alla funzione 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 

Dalla documentazione per l' useHashargomento:

logico che indica se è necessario utilizzare la versione hash dell'algoritmo. Può essere usato solo per replace = FALSE, prob = NULL e size <= n / 2, e in realtà dovrebbe essere usato per n di grandi dimensioni, poiché useHash = FALSE utilizzerà la memoria proporzionale a n.


Interessante! Questo sembra essere.
passerby51

Ora, mi chiedo se è possibile confrontare la quantità di memoria utilizzata dall'hash "sample.int" rispetto a igraph :: sample_seq (?)
passerby51
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.