- 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))