由于 R 计算向量运算的速度非常快,因此在进行性能编程时要记住的最重要的事情是对尽可能多的运算进行向量化。
这意味着要认真考虑用向量运算替换循环。这是我的快速卷积解决方案(每个长度为 1000 的输入向量快 50 倍):
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
}
您会注意到内部循环(for j in ...)已经消失。相反,我用向量运算替换了它。 j 现在定义为向量 (j
j <- 1:ny
ij <- i + j - 1
xy[i+(1:ny)-1] <- xy[ij] + x[i] * y
我写了一个小函数来衡量性能:
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")
}
对于两个长度各为 1000 的向量,我获得了 98% 的性能提升:
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