Last active
February 13, 2024 15:32
-
-
Save jrosell/7a38c8731a4002425e5e39bce35fd0e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# preallocates memory. | |
fmat <- function(n) { | |
res <- matrix(NA, n, n) | |
for (i in 1:n) { | |
res[i, ] <- runif(n) | |
} | |
res | |
} | |
# rbind each time | |
frbind <- function(n) { | |
res <- vector() | |
for (i in 1:n) { | |
res <- rbind(res, runif(n)) | |
} | |
res | |
} | |
# growing the final matrix in chunks | |
fchunks <- function(n, csize = 10) { | |
chunk <- matrix(NA, csize, n) | |
res <- vector() | |
for (i in 1:n) { | |
if (i %% csize == 0) { | |
chunk[csize, ] <- runif(n) | |
res <- rbind(res, chunk) | |
chunk <- matrix(NA, csize, n) | |
} else { | |
chunk[i %% csize, ] <- runif(n) | |
} | |
} | |
res[!is.na(res[, 1]), ] | |
} | |
# grow list which is converted to a matrix at the end. | |
flist <- function(n) { | |
res <- list() | |
for (i in 1:n) { | |
res[[length(res) + 1]] <- runif(n) | |
} | |
do.call(rbind, res) | |
} | |
# Using cbind might, given that R mostly deals in columns. | |
fcbind <- function(n) { | |
res <- vector() | |
for (i in 1:n) { | |
res <- cbind(res, runif(n)) | |
} | |
t(res) | |
} | |
fpurrr <- function(n) { | |
x <- purrr::map(1:n, \(x) runif(n)) | |
len <- length(x) | |
res <- x |> purrr::list_c() | |
dim(res) <- c(len, len) | |
res | |
} | |
fmatrixbyrow <- function(n) { | |
x <- lapply(1:n, function(x) runif(n)) | |
len <- length(x) | |
res <- matrix(as.numeric(unlist(x)), nrow = len, byrow = TRUE) | |
res | |
} | |
fpurrr2 <- function(n) { | |
res <- purrr::map(1:n, \(x) runif(n)) | |
do.call(rbind, res) | |
} | |
flist2 <- function(n) { | |
res <- list() | |
for (i in 1:n) { | |
res[[length(res) + 1]] <- runif(n) | |
} | |
len <- length(res) | |
res <- res |> purrr::list_c() | |
dim(res) <- c(len, len) | |
res | |
} | |
flist3 <- function(n) { | |
res <- list() | |
for (i in 1:n) { | |
res[[length(res) + 1]] <- runif(n) | |
} | |
len <- length(res) | |
res <- matrix(as.numeric(unlist(res)), nrow = len, byrow = TRUE) | |
res | |
} | |
fvec0 <- function(n) { | |
res <- vector(mode = "list") | |
for (i in 1:n) { | |
res[[length(res) + 1]] <- runif(n) | |
} | |
do.call(rbind, res) | |
} | |
fvec2 <- function(n) { | |
res <- vector(mode = "list") | |
for (i in 1:n) { | |
res[[length(res) + 1]] <- runif(n) | |
} | |
len <- length(res) | |
res <- res |> purrr::list_c() | |
dim(res) <- c(len, len) | |
res | |
} | |
n <- 1000 | |
bench <- microbenchmark::microbenchmark( | |
fmat(n), | |
frbind(n), | |
fcbind(n), | |
fchunks(n, csize = 100), | |
flist(n), | |
fpurrr(n), | |
fpurrr2(n), | |
fmatrixbyrow(n), | |
flist2(n), | |
flist3(n), | |
times = 30, unit = "ms" | |
) | |
bench |> print() | |
n <- 10000 | |
bench2 <- microbenchmark::microbenchmark( | |
flist(n), | |
flist2(n), | |
flist3(n), | |
times = 30, unit = "ms" | |
) | |
n <- 10000 | |
bench3 <- bench::mark( | |
fmat(n), | |
flist(n), | |
flist2(n), | |
fvec0(n), | |
fvec2(n), | |
min_iterations = 30, check = FALSE, time_unit = "ms", filter_gc = FALSE | |
) | |
bench3 |> print() |
Here the results I get using n=10000 for the most promising options using a for loop and without preacollacting memory.
Unit: milliseconds
expr min lq mean median uq max neval cld
flist(n) 2165.015 2564.815 2939.605 2819.418 3165.993 5139.394 30 a
flist2(n) 1444.778 1619.172 1822.930 1767.477 2028.077 2371.247 30 b
flist3(n) 2632.312 3194.872 3491.858 3451.352 3705.835 4765.866 30 c
Here the results, including memory allocation using n=10000
expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result memory time gc
<bch:expr> <dbl> <dbl> <dbl> <bch:byt> <dbl> <int> <dbl> <dbl> <list> <list> <list> <list>
1 fmat(n) 2864. 3057. 0.322 2.26GB 0.633 30 59 93221. <NULL> <Rprofmem> <bench_tm [30]> <tibble>
2 flist(n) 2613. 2672. 0.364 1.52GB 0.462 30 38 82327. <NULL> <Rprofmem> <bench_tm [30]> <tibble>
3 flist2(n) 1737. 1972. 0.453 1.52GB 0.726 30 48 66155. <NULL> <Rprofmem> <bench_tm [30]> <tibble>
4 fvec0(n) 2567. 2899. 0.318 1.52GB 0.637 30 60 94193. <NULL> <Rprofmem> <bench_tm [30]> <tibble>
5 fvec2(n) 1748. 2036. 0.478 1.52GB 0.956 30 60 62766. <NULL> <Rprofmem> <bench_tm [30]> <tibble>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here the results I get using n=1000