我有一个R代码,可以进行两个函数的卷积...
convolveSlow <- function(x, y) {
nx <- length(x); ny <- length(y)
xy <- numeric(nx + ny - 1)
for(i in seq(length = nx)) {
xi <- x[[i]]
for(j in seq(length = ny)) {
ij <- i+j-1
xy[[ij]] <- xy[[ij]] + xi * y[[j]]
}
}
xy
}
Run Code Online (Sandbox Code Playgroud)
有没有办法删除两个for循环并使代码运行得更快?
谢谢你
And*_*rie 18
由于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
}
Run Code Online (Sandbox Code Playgroud)
你会注意到内环(对于j in ...)已经消失了.相反,我用矢量操作替换它.j现在被定义为向量(j < - 1:ny).另请注意,我引用整个向量y,而不是对其进行子集化(即y而不是y [j]).
j <- 1:ny
ij <- i + j - 1
xy[i+(1:ny)-1] <- xy[ij] + x[i] * y
Run Code Online (Sandbox Code Playgroud)
我写了一个小函数来测量性能:
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")
}
Run Code Online (Sandbox Code Playgroud)
对于每个长度为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
Run Code Online (Sandbox Code Playgroud)