Функція «вибірки» для порівняльної оцінки в R


11

Я оцінював sampleфункцію в R і порівнював її з 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))

Я отримую такий результат:

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

Але коли я бігаю, наприклад,

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

Я отримую набагато швидший результат для 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

Здається, що коли Nпотужність 10 (чи якесь інше спеціальне число?) sampleНабагато швидше, ніж інші менші N, які не мають сили 10. Це очікувана поведінка чи мені щось не вистачає?

Відповіді:


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 

З документації для useHashаргументу:

логічне вказівка, чи слід використовувати хеш-версію алгоритму. Можна використовувати лише для заміни = FALSE, prob = NULL та розмір <= n / 2, і дійсно слід використовувати для великих n, оскільки useHash = FALSE буде використовувати пам'ять, пропорційну n.


Цікаво! Це, здається, все.
перехожий51

Тепер мені цікаво, чи можна порівняти, скільки пам’яті використовує хеш «sample.int» та igraph :: sample_seq (?)
passerby51
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.