請看看是否有辦法讓以下在 R 中運行得更快,大部分時間都花在 qbeta 上
numSim <- 1000
numDay <- 365*4
dailyFreq <- 288
maximumVolume <- 15
alphaParam <- 20
betaParam <- 30
t0 = Sys.time()
randomNumber <- matrix(runif(numSim * numDay * dailyFreq), ncol = numSim, byrow = FALSE)
t1 = Sys.time()
t1 - t0
effect <- qbeta(randomNumber, alphaParam, betaParam) * maximumVolume
Sys.time() - t1
uj5u.com熱心網友回復:
正如@Roland 所建議的,一個可能的解決方案是拆分 randomNumber 并并行運行該函式。我是庫“future.apply”的粉絲,所以我用它實作了一個解決方案。另外,我不太喜歡 Sys.time() 測量運行時間的方法,當使用像 Rstudio 這樣的介面時,它可能會產生錯誤。所以我用另一種方法來找到函式的運行時間。
請注意,我還將變數“numSim”從 1000 更改為 50 以進行快速測驗。
library(future.apply)
numSim <- 50
numDay <- 365*4
dailyFreq <- 288
maximumVolume <- 15
alphaParam <- 20
betaParam <- 30
randomNumber <- matrix(runif(numSim * numDay * dailyFreq), ncol = numSim, byrow = FALSE)
system.time(effect1 <- qbeta(randomNumber, alphaParam, betaParam) * maximumVolume)
這給出了:
user system elapsed
60.077 0.103 60.271
然后是帶有 future_apply 的并行版本:
plan(multisession)
system.time(effect<-future_apply(randomNumber, 2, function(x, alphaParam, betaParam, maximumVolume){
return(qbeta(x, alphaParam, betaParam)*maximumVolume)
}, alphaParam=alphaParam, betaParam=betaParam, maximumVolume=maximumVolume ) )
這給出了:
user system elapsed
2.467 0.556 22.361
uj5u.com熱心網友回復:
將runif值傳遞給qbeta只是提供隨機的 beta 變數(其中 4.2e8)。你可以使用rbeta:
effect1 <- matrix(rbeta(numSim*numDay*dailyFreq, alphaParam, betaParam)*maximumVolume, ncol = numSim)
它在我的機器上快了大約 14 倍:
library(microbenchmark)
numSim <- 10
numDay <- 365*4
dailyFreq <- 288
maximumVolume <- 15
alphaParam <- 20
betaParam <- 30
f1 <- function() {
randomNumber <- matrix(runif(numSim * numDay * dailyFreq), ncol = numSim, byrow = FALSE)
return(qbeta(randomNumber, alphaParam, betaParam)*maximumVolume)
}
f2 <- function() {
return(matrix(rbeta(numSim*numDay*dailyFreq, alphaParam, betaParam)*maximumVolume, ncol = numSim))
}
microbenchmark(f1(), f2(), times = 10)
> microbenchmark(f1(), f2(), times = 10)
Unit: milliseconds
expr min lq mean median uq max neval
f1() 10630.2050 11207.2655 11236.32 11290.4811 11371.5236 11526.125 10
f2() 764.2666 795.6046 803.63 802.5437 814.4193 839.147 10
更新:future.apply按照 Fabrizio 的建議使用這種方法可以將運行時間從原始代碼減少約 25 倍,包括設定多會話的時間:
library(future.apply)
numSim <- 1000
f3 <- function() {
plan(multisession)
return(matrix(future_replicate(numSim, rbeta(numDay*dailyFreq, alphaParam, betaParam)*maximumVolume), ncol = numSim))
}
microbenchmark(f2(), f3(), times = 1)
> microbenchmark(f2(), f3(), times = 1)
Unit: seconds
expr min lq mean median uq max neval
f2() 81.57298 81.57298 81.57298 81.57298 81.57298 81.57298 1
f3() 44.93711 44.93711 44.93711 44.93711 44.93711 44.93711 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/324576.html
下一篇:通過識別函式的瓶頸來改進速度函式
