how to speed up your r code with virtually no effort

Post on 05-Feb-2016

51 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

How to Speed Up Your R Code With Virtually No Effort. Alec Stephenson. What I am Talking About. Basic Principals system.time(), benchmark() in rbenchmark Profiling R Code Rprof() Parallel Programming mclapply() parLapply() in parallel Using R With Amazon EC2. - PowerPoint PPT Presentation

TRANSCRIPT

How to Speed Up Your R Code With Virtually No Effort

Alec Stephenson

What I am Talking About

• Basic Principals system.time(), benchmark() in rbenchmark

• Profiling R Code Rprof()

• Parallel Programming mclapply() parLapply() in parallel

• Using R With Amazon EC2

What I am Not Talking About

• Writing complied code (e.g. C/C++)• Parallelizing compiled code (e.g. OpenMP)• Byte code compiler for R• Is code optimization worth your time?• Is code optimization worth turning your code

into an unreadable mess?

Basic Principals

• Vectorize rather than loop• Allocate memory up front• Get to the compiled code faster

.C .Fortran .External .Internal .Call .Primitive

• R can be unpredictable

Vectorize rather than loop

x <- rnorm(1e06); y <- rnorm(1e06)

0.01s, Good:z <- x + y

6.23s, Bad:z <- numeric(1e06)for(i in 1:1e06) z[i] <- x[i] + y[i]

Allocate memory up front

x <- rnorm(1e06); y <- rnorm(1e06)

0.01s, Good:z <- x + y

One Hour, Terrible:z <- NULLfor(i in 1:1e06) z[i] <- x[i] + y[i]

Get to the compiled code faster

Get to the compiled code faster

Get to the compiled code faster

Could you:

• Use pmax() rather than ifelse()• Use tabulate() rather than table()• Use lapply(split()) rather than tapply()• etc...

Get to the compiled code faster

x <- rnorm(1e07); y <- rnorm(1e07)

0.42s, Good:pmax(x, y)

3.09s, Bad:ifelse(x < y, y, x)

R can be unpredictablex <- rnorm(1e08); y <- rnorm(50); n <- 100000

0.14s, 0.11s, Good:sum(x)/length(x), for(i in 1:n) sum(y)/length(y)

0.28s, 0.98s, Not So Good:mean(x), for(i in 1:n) mean(y)

R can be unpredictablex <- rnorm(1e08); y <- rnorm(50); n <- 100000

0.28s, 0.98s, Not So Good:mean(x), for(i in 1:n) mean(y)

0.28s, 0.26s, Improves In Loop:mean.default(x), for(i in 1:n) mean.default(y)

0.28s, 0.06s, Improves A Lot In Loop:.Internal(mean(x)), for(i in 1:n) .Internal(mean(y))

R can be unpredictablex <- rnorm(50); y <- rnorm(50); n <- 100000

0.06s:for(i in 1:n) x + y

0.12s, Seriously!:for(i in 1:n) (((((x + y)))))

Profiling R Code

• Very simple do to and always useful• Often surprising (R can be unpredictable)• Indicates where to concentrate your

optimization efforts• Large potential gains for virtually no effort• A small piece of code often takes up virtually

all the running time

Profiling R Code

Rprof()## run some code here e.g. BadIdea(100000)Rprof(NULL)summaryRprof()

This function is stupid

BadIdea <- function(n) { x <- seq(-1, 1, length=n) y <- numeric(n) for (i in 1:n) y[i] <-((det(as.matrix(x[i]))*2)^1.1)/n y}

Profiling R Code$by.self self.time self.pct total.time total.pctas.matrix 1.14 20.00 1.96 34.39determinant 0.96 16.84 3.78 66.32determinant.matrix 0.76 13.33 0.86 15.09det 0.72 12.63 5.16 90.53$ 0.66 11.58 0.66 11.58array 0.62 10.88 0.70 12.28BadIdea 0.44 7.72 5.70 100.00as.matrix.default 0.12 2.11 0.82 14.39^ 0.10 1.75 0.10 1.75as.vector 0.08 1.40 0.08 1.40ncol 0.06 1.05 0.06 1.05nrow 0.04 0.70 0.04 0.70

Profiling R Code

$by.total total.time total.pct self.time self.pctBadIdea 5.70 100.00 0.44 7.72det 5.16 90.53 0.72 12.63determinant 3.78 66.32 0.96 16.84as.matrix 1.96 34.39 1.14 20.00determinant.matrix 0.86 15.09 0.76 13.33as.matrix.default 0.82 14.39 0.12 2.11array 0.70 12.28 0.62 10.88$ 0.66 11.58 0.66 11.58^ 0.10 1.75 0.10 1.75as.vector 0.08 1.40 0.08 1.40ncol 0.06 1.05 0.06 1.05nrow 0.04 0.70 0.04 0.70

Parallel Programming

Multicore: single machine, not windowsSnow: multiple machines, any OS

Parallel: snow plus multicore mclapply(x, FUN, ..., mc.cores) parLapply(cl, x, FUN)Foreach: front-end for easier coding

Parallel Programming

fn <- function(a) a * 1:10lapply(c(22,56,70,43), fn)

mclapply(c(22,56,70,43), fn, mc.cores = 4)

cl <- makeCluster(4)parLapply(cl, c(22,56,70,43), fn)stopCluster(cl)

Parallel Programming

Parallel random forest function (multicore type):

parRandomForest <- function(xx, ..., ntree = 500, mc = 1) { rfwrap <- function(ntree, xx, ...) randomForest(x=xx,

ntree=ntree, ...) rfpar <- mclapply(rep(ceiling(ntree/mc), mc), rfwrap,

xx=xx, ..., mc.cores = mc) do.call(combine, rfpar) # not very fast}

Amazon EC2• Like Hiring One or More Powerful Computers By

The Hour• Start Amazon EC2 Instance(s)• AMIs available with R and R Studio Server pre-

installed • $1.8 per hour (or part hour) for quadruple extra

large high memory instance with linux 64-bit OS:68.4 GB of memory26 EC2 Compute Units (8 virtual cores)

Important Talk Clarification:

When I answered ‘it’s important to turn it off’ I should have said ‘it’s important to turn off the instance explicitly by terminating (or stopping) it’. If you only turn off your computer, the EC2 instance will continue to run and you will continue to be charged by the hour.

Thanks for attending, Alec.

top related