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, 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=10000 for the most promising options using a for loop and without preacollacting memory.