Benchmarking der Beispielfunktion in R.

11

Ich habe das Benchmarking durchgeführt sample Funktion in R verglichen und mit ihr verglichen igraph:sample_seqund auf ein seltsames Ergebnis gestoßen.

Wenn ich so etwas wie:

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

Ich bekomme ein Ergebnis wie dieses:

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

Aber wenn ich zum Beispiel renne,

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

Ich bekomme ein viel schnelleres Ergebnis für 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

Es scheint, dass wenn Neine Potenz von 10 (oder eine andere spezielle Zahl?) sampleViel schneller ist als andere kleinere N, die keine Potenzen von 10 sind. Ist dies das erwartete Verhalten oder fehlt mir etwas?

Passant51
quelle

Antworten:

10

sample() oder eher sample.int() verwendet standardmäßig einen Hash-Algorithmus, wenn bestimmte Bedingungen erfüllt sind, eine davon ist n> 1e7.

Wenn der zweite Benchmark ohne Hashing erneut ausgeführt wird, werden Sie feststellen, dass er auch viel langsamer als die igraph-Funktion ist.

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 

Aus der Dokumentation zum useHashArgument:

logische Angabe, ob die Hash-Version des Algorithmus verwendet werden soll. Kann nur für replace = FALSE, prob = NULL und size <= n / 2 verwendet werden und sollte wirklich für große n verwendet werden, da useHash = FALSE Speicher proportional zu n verwendet.

H 1
quelle
Interessant! Das scheint es zu sein.
Passant51
Nun frage ich mich , ob es möglich ist , wie viel Speicher zu vergleichen die gehasht „sample.int“ Anwendungen im Vergleich zu IGRAPH :: sample_seq (?)
passerby51