20 juillet 2018
void byValue (vec x, double newValue) { x.fill(newValue); } void byRef (vec& x, double newValue) { x.fill(newValue); } void byRefSafe (const vec& x, double newValue) { x.fill(newValue); }
x <- 1:5 + .1 x %>% byValue(3.14) x
## [1] 1.1 2.1 3.1 4.1 5.1
x %>% byRef(3.14) x
## [1] 3.14 3.14 3.14 3.14 3.14
x <- 1:5 x %>% byRef(3.14) x
## [1] 1 2 3 4 5
mat prodByValue (mat X, mat Y) { return X*Y; } mat prodByRef (mat& X, mat& Y) { return X*Y; }
X <- matrix(rnorm(10000), 100, 100) Y <- matrix(rnorm(10000), 100, 100) tm <- microbenchmark(prodByValue(X, Y), prodByRef(X, Y))
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.
vec invProdCpp (mat A, vec b) { return A.i() * b; } vec solveCpp (mat A, vec b) { return solve(A, b); }
A <- matrix(rnorm(10000), 100, 100) b <- rnorm(100) tm <- microbenchmark(invProdCpp(A, b), solveCpp(A, b), solve(A) %*% b, solve(A, b))
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.
mat covOutOfScope (mat X) { mat y = zeros(X.n_cols, X.n_cols); rowvec z = rowvec(X.n_cols); for (uword i = 0; i < X.n_rows; i++) { z = X.row(i); y += z.t() * z; } return y / X.n_rows; }
mat covInScope (mat X) { mat y = zeros(X.n_cols, X.n_cols); for (uword i = 0; i < X.n_rows; i++) { rowvec z = X.row(i); y += z.t() * z; } return y / X.n_rows; }
X <- matrix(rnorm(10000), 100, 100) tm <- microbenchmark(covOutOfScope(X), covInScope(X)) autoplot(tm)
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.
mat prodByRowOrdering (mat A, mat B) { mat C = mat(size(A)); for (uword i = 0; i < A.n_rows; i++) for (uword j = 0; j < A.n_cols; j++) C(i,j) = A(i,j) * B(i,j); return C; }
mat prodByColOrdering (mat A, mat B) { mat C = mat(size(A)); for (uword j = 0; j < A.n_cols; j++) for (uword i = 0; i < A.n_rows; i++) C(i,j) = A(i,j) * B(i,j); return C; }
A <- matrix(rnorm(10000), 100, 100) B <- matrix(rnorm(10000), 100, 100) tm <- microbenchmark(prodByColOrdering(A, B), prodByRowOrdering(A, B)) autoplot(tm)
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.
In Rstudio it is easy to identify which part of code is worth coding in C++. This operation is called profiling and documentation are available here:
To quicky begin profiling one can select a part of code and then click on Profile > Profile Selected Lines (shortcut Ctrl+Alt+Shift+P).
The package loaded and used is profvis and similarly as microbenchmark it can be run to establish a comparison of function. It will get the time spent line by line of the code.
library(profvis) profvis({ data1 <- data # Four different ways of getting column means means <- apply(data1[, names(data1) != "id"], 2, mean) means <- colMeans(data1[, names(data1) != "id"]) means <- lapply(data1[, names(data1) != "id"], mean) means <- vapply(data1[, names(data1) != "id"], mean, numeric(1)) })