- Why Is My Code So Slow?
- Approaches To Accelerating
- Remarks
February 11, 2016
There are many factors that may play a role…
\[\hat{y}=X(X'X)^{-1}X'y\]
reg1 = function(x, y) { x %*% solve(t(x) %*% x) %*% t(x) %*% y }
reg2 = function(x, y) { x %*% (solve(t(x) %*% x) %*% (t(x) %*% y)) }
reg3 = function(x, y) { x %*% solve(crossprod(x), crossprod(x, y)) }
library(rbenchmark) set.seed(123) n = 2000 p = 500 x = matrix(rnorm(n * p), n) y = rnorm(n) benchmark(reg1(x, y), reg2(x, y), reg3(x, y), columns = c("test", "replications", "elapsed", "relative"), replications = 10)
test replications elapsed relative 1 reg1(x, y) 10 18.33 6.891 2 reg2(x, y) 10 3.93 1.477 3 reg3(x, y) 10 2.66 1.000
crossprod(x, y)
for \(X'y\)
crossprod(x)
for \(X'X\)
solve(A, b)
for \(A^{-1}b\)princomp()
library(rARPACK) ## For svds() pca2 = function(x, k) { xc = scale(x, center = TRUE, scale = FALSE) decomp = svds(xc, k, nu = 0, nv = k) xc %*% decomp$v }
benchmark(princomp(x), pca2(x, 10), columns = c("test", "replications", "elapsed", "relative"), replications = 10)
test replications elapsed relative 2 pca2(x, 10) 10 2.94 1.000 1 princomp(x) 10 8.90 3.027
set.seed(123) x = matrix(rnorm(2000^2), 2000) system.time(crossprod(x))
user system elapsed 3.95 0.00 3.95
user system elapsed 0.76 0.00 0.20
readr
package provides alternatives to read.table()
and read.csv()
read_delim()
and read_csv()
library(readr) system.time(read.csv("train.csv")) ## Base R
user system elapsed 27.24 0.81 28.07
system.time(read_csv("train.csv")) ## readr
user system elapsed 4.77 0.27 5.03
apply()
library(matrixStats) benchmark(apply(x, 2, sd), colSds(x), columns = c("test", "replications", "elapsed", "relative"))
test replications elapsed relative 1 apply(x, 2, sd) 100 2.94 8.647 2 colSds(x) 100 0.34 1.000
library(RcppEigen) benchmark(lm.fit(x, y), reg3(x, y), fastLmPure(x, y, method = 2), columns = c("test", "replications", "elapsed", "relative"), replications = 10)
test replications elapsed relative 3 fastLmPure(x, y, method = 2) 10 0.68 1.000 1 lm.fit(x, y) 10 3.81 5.603 2 reg3(x, y) 10 2.71 3.985
\[f(x,y)\propto x^2\exp\{-xy^2-y^2+2y-4x\}\]
gibbs = function(N, thin) { iter = 1:N xvec = numeric(N) yvec = numeric(N) x = 0 y = 0 for(i in 1:N) { for(j in 1:thin) { x = rgamma(1, shape = 3, scale = 1 / (y * y + 4)) y = rnorm(1, 1 / (x + 1), 1 / sqrt(2 * x + 2)) } xvec[i] = x yvec[i] = y } data.frame(Iter = iter, x = xvec, y = yvec) }
#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] DataFrame gibbs_rcpp(int N, int thin) { IntegerVector iter(N); for(int i = 0; i < N; i++) iter[i] = i + 1; NumericVector xvec(N); NumericVector yvec(N); double x = 0.0, y = 0.0; for(int i = 0; i < N; i++) { for(int j = 0; j < thin; j++) { x = R::rgamma(3.0, 1.0 / (y * y + 4.0)); y = R::rnorm(1.0 / (x + 1.0), 1.0 / std::sqrt(2.0 * x + 2.0)); } xvec[i] = x; yvec[i] = y; } return DataFrame::create(Named("Iter") = iter, Named("x") = xvec, Named("y") = yvec); }
using Distributions using DataFrames function gibbs_jl(N, thin) iter = 1:N xvec = zeros(N) yvec = zeros(N) x = 0.0 y = 0.0 for i = 1:N for j = 1:N x = rand(Gamma(3.0, 1.0 / (y * y + 4.0))) y = rand(Normal(1.0 / (x + 1.0), 1.0 / sqrt(2.0 * x + 2.0))) end xvec[i] = x yvec[i] = y end DataFrame(Iter = iter, x = xvec, y = yvec) end
set.seed(123) system.time(res_r <- gibbs(1000, 1000))
user system elapsed 5.17 0.00 5.17
set.seed(123) system.time(res_rcpp <- gibbs_rcpp(1000, 1000))
user system elapsed 0.20 0.00 0.21
identical(res_r, res_rcpp)
[1] TRUE
srand(123) @elapsed res_jl = gibbs_jl(1000, 1000)
0.098107808
library(ggplot2) ggplot(res, aes(x = x, y = y)) + geom_point()
using Gadfly draw(SVG("gibbs_jl.svg", 6inch, 6inch), plot(res_jl, x = "x", y = "y", Geom.point))