Avoid two for loops in R

前端 未结 6 745
执念已碎
执念已碎 2021-02-08 11:15

I have a R code that can do convolution of two functions...

convolveSlow <- function(x, y) {  
nx <- length(x); ny <- length(y)  
xy <- numeric(nx          


        
6条回答
  •  执念已碎
    2021-02-08 11:44

    Since R is very fast at computing vector operations, the most important thing to keep in mind when programming for performance is to vectorise as many of your operations as possible.

    This means thinking hard about replacing loops with vector operations. Here is my solution for fast convolution (50 times faster with input vectors of length 1000 each):

    convolveFast <- function(x, y) {
        nx <- length(x)
        ny <- length(y)
        xy <- nx + ny - 1
        xy <- rep(0, xy)
        for(i in (1:nx)){
            j <- 1:ny
            ij <- i + j - 1
            xy[i+(1:ny)-1] <- xy[ij] + x[i] * y
        }
        xy
    }
    

    You will notice that the inner loop (for j in ...) has disappeared. Instead, I replaced it with a vector operation. j is now defined as a vector (j <- 1:ny). Notice also that I refer to the entire vector y, rather than subsetting it (i.e. y instead of y[j]).

    j <- 1:ny
    ij <- i + j - 1
    xy[i+(1:ny)-1] <- xy[ij] + x[i] * y
    

    I wrote a small function to measure peformance:

    measure.time <- function(fun1, fun2, ...){
        ptm <- proc.time()
        x1 <- fun1(...)
        time1 <- proc.time() - ptm
    
        ptm <- proc.time()
        x2 <- fun2(...)
        time2 <- proc.time() - ptm
    
        ident <- all(x1==x2)
    
        cat("Function 1\n")
        cat(time1)
        cat("\n\nFunction 2\n")
        cat(time2)
        if(ident) cat("\n\nFunctions return identical results")
    
    }
    

    For two vectors of length 1000 each, I get a 98% performance improvement:

    x <- runif(1000)
    y <- runif(1000)
    measure.time(convolveSlow, convolveFast, x, y)
    
    Function 1
    7.07 0 7.59 NA NA
    
    Function 2
    0.14 0 0.16 NA NA
    
    Functions return identical results
    

提交回复
热议问题