Sys.setenv("PKG_CXXFLAGS" = sprintf('-I"%s"', normalizePath(".", winslash = "/"))) Rcpp::sourceCpp(code = ' #define STRICT_R_HEADERS #define BOOST_ERROR_CODE_HEADER_ONLY // [[Rcpp::depends(BH)]] // [[Rcpp::plugins(cpp11)]] #include <Rcpp.h> #include <blaze/Blaze.h> using blaze::unaligned; using blaze::unpadded; using blaze::columnMajor; using blaze::CustomMatrix; using blaze::CustomVector; using blaze::DynamicVector; //[[Rcpp::export]] Rcpp::NumericVector blaze_mv(Rcpp::NumericMatrix X, Rcpp::NumericVector Y) { // input cheching if (X.ncol() != Y.size()) Rcpp::stop("The size of Y must be equal to the number of columns of X."); // map and perform matrix-vector multiplication CustomMatrix<double, unaligned, unpadded, columnMajor> a(&X[0], X.nrow(), X.ncol()); CustomVector<double, unaligned, unpadded> b(&Y[0], Y.size()); DynamicVector<double> c = a * b; // output Rcpp::NumericVector out(c.size()); for (auto i = 0; i < c.size(); ++i) out[i] = c[i]; return out; }')
library(microbenchmark) N <- 5000L X <- matrix(rnorm(N**2), N, N) y <- rnorm(N) microbenchmark( blaze_mv = blaze_mv(X, y), R_mv = as.vector(X %*% y), times = 50L ) # Unit: milliseconds # expr min lq mean median uq max neval # blaze_mv 10.09042 10.32564 11.70235 10.93375 12.88094 15.67995 50 # R_mv 32.24726 33.52491 35.97026 35.66461 37.98600 42.05827 50