2012-01-08 8 views
4

次のwhileループを高速化する方法はありますか?ループ中のループを加速する

上記のコメントのように金額をワークアウト
count <- function(start, stepsize, threshold) { 
    i <- 1; 
    while (start <= threshold) { 
    start <- stepsize*i+start; 
    i <- i+1; 
    } 
    return(i-1); 
} 

system.time(count(1, 0.004, 1e10)) 
+1

この特定の問題については、私はうまくいくでしょう手での合計 - 例: 1からnまでのsum(i)がn *(n + 1)であることを知っていれば、適切な2次方程式を解いて調整します。あなたはバイトコンパイルすることもできます...大きな問題のこの部分ですか、この正確な問題を解決するだけですか? –

+0

それはそれです!どうもありがとう! – rua

答えて

10

## start + S*n*(n-1)/2 = T 
## (T-start)*2/S = n*(n-1) 
## n*(n-1) - (T-start)*2/S = 0 

この二次方程式を解くための機能:このソリューションは、本質的に時間がかかりません

ff <- function(start,stepsize,threshold) { 
    C <- (threshold-start)*2/stepsize 
    ceiling((-1 + sqrt(1+4*C))/2) 
} 

...

> system.time(cc <- count(1, 0.004, 1e10)) 
    user system elapsed 
    5.372 0.056 5.642 
> system.time(cc2 <- ff(1, 0.004, 1e10)) 
    user system elapsed 
     0  0  0 
> cc2 
[1] 2236068 
> cc 
[1] 2236068 

qu estionは、これがあなたが解決する必要がある正確な問題に一般化するかどうかです。あなたがこれをやろうとしているよう

0

に見えます:

recount <- function(start, stepsize, threshold) { 
    NewCount <<- floor((threshold-start)/stepsize) 
} 
(fast <- system.time(recount(1, 0.004, 1e10))) 

は、それは、測定時間がかかりません。ここでは、グローバル変数なし

が、それは次のようになります。

recount <- function(start, stepsize, threshold) { 
    return(floor((threshold-start)/stepsize)) 
} 
(fast <- system.time(NewCount <- recount(1, 0.004, 1e10))) 
+1

??これはOPのテストコードと同じ答えを与えません...そして、値を返すのではなくグローバル変数を設定することは、むしろ単体的です... –

0

面白いブログはいくつかのヒントとRのループを高速化する方法がある

Another aspect of speeding up loops in R

ですそのページで報告されている例

NROW=5000 
NCOL=100 

#Ex. 1 - Creation of a results matrix where its memory 
#allocation must continually be redefined 
t1 <- Sys.time() 
x <- c() 
for(i in seq(NROW)){ 
    x <- rbind(x, runif(NCOL)) 
} 
T1 <- Sys.time() - t1 


#Ex. 2 - Creation of a results matrix where its memory 
#allocation is defined only once, at the beginning of the loop. 
t2 <- Sys.time() 
x <- matrix(NA, nrow=NROW, ncol=NCOL) 
for(i in seq(NROW)){ 
    x[i,] <- runif(NCOL) 
} 
T2 <- Sys.time() - t2 


#Ex. 3 - Creation of a results object as an empty list of length NROW. 
#Much faster than Ex. 1 even though the size of the list is 
#not known at the start of the loop. 
t3 <- Sys.time() 
x <- vector(mode="list", NROW) 
for(i in seq(NROW)){ 
    x[[i]] <- runif(NCOL) 
} 
T3 <- Sys.time() - t3 

png("speeding_up_loops.png") 
barplot(c(T1, T2, T3), names.arg = c("Concatenate result", "Fill empty matrix", "Fill empty list"),ylab="Time in seconds") 
dev.off() 

T1;T2;T3