ускорить пока цикл в R - PullRequest
       4

ускорить пока цикл в R

3 голосов
/ 08 января 2012

Как я могу ускорить следующий цикл 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))

Ответы [ 3 ]

10 голосов
/ 08 января 2012

Вычисление сумм, как в комментарии выше:

## 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

Вопрос в том, обобщает ли это именно ту проблему, которую нужно решить.

0 голосов
/ 19 марта 2013

Есть интересный блог о том, как ускорить цикл в R с некоторыми советами

Еще один аспект ускорения циклов в 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
0 голосов
/ 09 января 2012

Похоже, что вы пытаетесь сделать это:

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)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...