Función de "muestra" de evaluación comparativa en R

11

Estaba samplecomparando la función en R y comparándola con igraph:sample_sequn resultado extraño.

Cuando ejecuto algo como:

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

Obtengo un resultado como este:

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

Pero cuando corro, por ejemplo,

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

Obtengo un resultado mucho más rápido para 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

Parece que cuando Nes una potencia de 10 (o algún otro número especial?), sampleEs mucho más rápido que otros más pequeños Nque no son potencias de 10. ¿Es este comportamiento esperado o me estoy perdiendo algo?

transeúnte51
fuente

Respuestas:

10

sample()o más bien, sample.int()de manera predeterminada, utiliza un algoritmo hash cuando se cumplen ciertas condiciones, una de ellas es n> 1e7.

Si el segundo punto de referencia se vuelve a ejecutar sin hashing, verá que también es mucho más lento que la función 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 documentación para el useHashargumento:

lógica que indica si se debe usar la versión hash del algoritmo. Solo se puede usar para replace = FALSE, prob = NULL y size <= n / 2, y realmente se debe usar para n grande, ya que useHash = FALSE usará memoria proporcional a n.

H 1
fuente
¡Interesante! Eso parece ser eso.
passerby51
Ahora, me pregunto si es posible comparar cuánta memoria utiliza el hash "sample.int" versus igraph :: sample_seq (?)
passerby51