【发布时间】:2016-10-26 13:45:20
【问题描述】:
我需要得到下面函数的结果
getScore <- function(history, similarities) {
nh<-ifelse(similarities<0, 6-history,history)
x <- nh*abs(similarities)
contados <- !is.na(history)
x2 <- sum(x, na.rm=TRUE)/sum(abs(similarities[contados]),na.rm=TRUE)
x2
}
例如对于以下向量:
notes <- c(1:5, NA)
history <- sample(notes, 1000000, replace=T)
similarities <- runif(1000000, -1,1)
这会在循环内发生变化。这需要:
ptm <- proc.time()
for (i in (1:10)) getScore(history, similarities)
proc.time() - ptm
user system elapsed
3.71 1.11 4.67
最初我怀疑问题出在for 循环上,但分析结果指向ifelse()。
Rprof("foo.out")
for (i in (1:10)) getScore(history, similarities)
Rprof(NULL)
summaryRprof("foo.out")
$by.self
self.time self.pct total.time total.pct
"ifelse" 2.96 65.78 3.48 77.33
"-" 0.24 5.33 0.24 5.33
"getScore" 0.22 4.89 4.50 100.00
"<" 0.22 4.89 0.22 4.89
"*" 0.22 4.89 0.22 4.89
"abs" 0.22 4.89 0.22 4.89
"sum" 0.22 4.89 0.22 4.89
"is.na" 0.12 2.67 0.12 2.67
"!" 0.08 1.78 0.08 1.78
$by.total
total.time total.pct self.time self.pct
"getScore" 4.50 100.00 0.22 4.89
"ifelse" 3.48 77.33 2.96 65.78
"-" 0.24 5.33 0.24 5.33
"<" 0.22 4.89 0.22 4.89
"*" 0.22 4.89 0.22 4.89
"abs" 0.22 4.89 0.22 4.89
"sum" 0.22 4.89 0.22 4.89
"is.na" 0.12 2.67 0.12 2.67
"!" 0.08 1.78 0.08 1.78
$sample.interval
[1] 0.02
$sampling.time
[1] 4.5
ifelse() 是我的性能瓶颈。 除非 R 中有一种方法可以加速 ifelse(),否则不可能有很大的性能提升。
但是,ifelse() 已经是矢量化方法。在我看来,剩下的唯一机会就是使用 C/C++。但是有没有办法避免使用编译后的代码?
【问题讨论】:
-
如果您只是想优化已经工作的代码,那么这是 CodeReview 问题而不是 StackOverflow 问题。 codereview.stackexchange.com
标签: r performance time vectorization