Улучшение производительности программы R с помощью Rcpp - PullRequest
1 голос
/ 20 мая 2019

Я пытаюсь ускорить мой код R - мне интересно, можно ли это сделать в Rcpp.Это мой код, который я начал писать.

library(Rcpp)

cppFunction('int cont.run_C(int reps=10000,int n=10000,int d=0.005,int l=10 ,int s=0.1) {
  r = rep(0, reps)
  theta = rep(0, n)
  for(int t = 0; t < reps; t++) {
    epsilon = rnorm(1, 0, d)
    Zt = sum(epsilon > theta ? 1 : epsilon < -theta ? -1: 0)
    r[t] = Zt / (l * n)
    theta = runif(n) < s ? abs(r[t]) : theta
  }
  return mean(r)
}')

system.time(cont.run_C())

1 Ответ

3 голосов
/ 21 мая 2019

Прежде чем пытаться перевести ваш код на C ++, имеет смысл сначала взглянуть на код R, особенно если вы не знаете C ++. Если вы используете профилировщик для своего кода, вы увидите, что большую часть времени тратится на две строки с ifelse. Тем не менее, обе линии могут быть улучшены. Первая строка эквивалентна:

Zt <- sum(epsilon > theta) - sum(epsilon < -theta)

Вторая строка может быть записана как

theta[runif(n) < s] <- abs(r[t])

Эти два изменения сокращают время выполнения в моей системе с более 10 секунд до менее 5 секунд. Снова посмотрев на результаты профилировщика, мы видим, что сейчас большая часть времени проводится в runif. Здесь мы можем использовать более быстрый ГСЧ из моего пакета dqrng , сократив время выполнения до 2 с. Конечный код:

library(dqrng)

cont.run <- function(reps=10000, n=10000, d=0.005, l=10 ,s=0.1) {
  r <- rep(0, reps)
  theta <- rep(0, n)
  for (t in 1:reps) {
    epsilon <- dqrnorm(1, 0, d)
    #Zt = sum(ifelse(epsilon > theta, 1, ifelse(epsilon < -theta, -1, 0)))
    Zt <- sum(epsilon > theta) - sum(epsilon < -theta)
    r[t] <- Zt / (l * n)
    theta[dqrunif(n) < s] <- abs(r[t])
  }
  return(mean(r))
}

system.time(cont.run())
#>        User      System verstrichen 
#>       1.804       0.244       2.049

Создано в 2019-05-21 с помощью представительного пакета (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...