Как упомянуто @Frank в комментариях, имеет смысл использовать tabulate
вместо sort
. Как только кто-то использует это, имеет смысл подумать о более быстрых методах выборки , как это предусмотрено в моем пакете dqrng :
library(dqrng)
m <- 1e6
bm <- bench::mark(sort(sample.int(m, replace = TRUE)),
tabulate(sample.int(m, replace = TRUE)),
sort(dqsample.int(m, replace = TRUE)),
tabulate(dqsample.int(m, replace = TRUE)),
check = FALSE)
bm[, 1:4]
#> # A tibble: 4 x 4
#> expression min median `itr/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl>
#> 1 sort(sample.int(m, replace = TRUE)) 72.3ms 75.5ms 13.2
#> 2 tabulate(sample.int(m, replace = TRUE)) 22.8ms 27.7ms 34.6
#> 3 sort(dqsample.int(m, replace = TRUE)) 59.5ms 64ms 15.3
#> 4 tabulate(dqsample.int(m, replace = TRUE)) 14.4ms 16.3ms 57.0
Создано в 2019-06-27 пакетом Представление (v0.3.0)
Обратите внимание, что я все еще использую R 3.5 на этой машине. С R 3.6 разница между sample.int
и dqsample.int
будет больше. Также обратите внимание, что для получения методов быстрой выборки больше не требуется версия разработки dqrng.
Можно также использовать RNG из dqrng через C ++, но это не имеет большого значения по сравнению с tabulate(dqsample.int(...))
по моему опыту:
#include <Rcpp.h>
// [[Rcpp::depends(dqrng, sitmo)]]
#include <dqrng_generator.h>
#include <convert_seed.h>
#include <R_randgen.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
Rcpp::IntegerVector sort_sample(uint32_t n) {
Rcpp::IntegerVector seed(2, dqrng::R_random_int);
auto rng = dqrng::generator(dqrng::convert_seed<uint64_t>(seed));
Rcpp::IntegerVector tab(n);
for (uint32_t i = 0; i < n; i++) {
uint32_t k = (*rng)(n);
tab[k]++;
}
return tab;
}