Unfortunately asplit is not faster.
L <- lapply(asplit(bigmat, 2), matrix, ncol=9)
Another option is to use as.data.frame.
lapply(unname(as.data.frame(bigmat)), matrix, ncol=9)
As both didn't show improvement an Rcpp version.
Rcpp::cppFunction('Rcpp::List m2l(Rcpp::NumericMatrix A) {
Rcpp::List output(A.ncol());
for(int i = 0; i < A.ncol(); ++i) {
output[i] = Rcpp::NumericMatrix(A.nrow()/9, 9, A.column(i).begin());
}
return output;
}')
m2l(bigmat)
Rcpp::cppFunction('Rcpp::List m2lB(Rcpp::NumericMatrix A) {
Rcpp::List output(A.ncol());
for(int i = 0; i < A.ncol(); ++i) {
Rcpp::NumericMatrix B = Rcpp::no_init(A.nrow()/9, 9);
for(int j = 0; j < A.nrow(); ++j) {
B[j] = A(j, i);
}
output[i] = B;
}
return output;
}')
m2lB(bigmat)
set.seed(0)
bigmat <- matrix(rnorm(252*90),252)
bench::mark(check=TRUE,
"apply" = apply(bigmat,2,function(x) matrix(x,ncol=9),simplify=F),
"asplit" = lapply(asplit(bigmat, 2), matrix, ncol=9),
"asDF" = lapply(unname(as.data.frame(bigmat)), matrix, ncol=9),
"Rcpp" = m2l(bigmat),
"RcppB" = m2lB(bigmat),
"array" = `attributes<-`(asplit(`dim<-`(bigmat, c(dim(bigmat)[[1]]/9L, 9L, dim(bigmat)[[2]])), 3), NULL),
"lapply" = lapply(
seq.int(ncol(m <- matrix(bigmat, nrow = nrow(bigmat) / 9)) / 9) - 1,
function(k) m[, 9 * k + (1:9)]
)
)
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time
# <bch:expr> <bch:t> <bch:t> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>
#1 apply 268.4µs 287.5µs 3416. 638KB 45.8 1269 17 371ms
#2 asplit 320.8µs 364.8µs 2529. 817KB 43.5 1046 18 414ms
#3 asDF 260.8µs 278.7µs 3476. 459KB 32.8 1484 14 427ms
#4 Rcpp 31.2µs 43.1µs 22611. 185KB 81.4 9165 33 405ms
#5 RcppB 29.4µs 36.9µs 26443. 185KB 98.2 9963 37 377ms
#6 array 261.9µs 283.8µs 3446. 812KB 57.2 1266 21 367ms
#7 lapply 138µs 156µs 6342. 402KB 51.4 2714 22 428ms
The Rcpp version is about 6 times faster than the original apply variant.