У меня есть некоторый опыт работы с C ++ и R, но я новичок в Rcpp. Недавно я имел огромный успех, используя Rcpp в некоторых из моих предыдущих проектов, поэтому решил применить его к новому проекту. Я был удивлен, что мой код Rcpp мог быть намного медленнее, чем соответствующая R-функция. Я попытался упростить свою функцию R, чтобы выяснить причину, но не могу найти никакой подсказки. Ваша помощь и комментарии приветствуются!
Основная функция R для сравнения реализаций R и Rcpp:
main <- function(){
n <- 50000
Delta <- exp(rnorm(n))
delta <- exp(matrix(rnorm(n * 5), nrow = n))
rx <- matrix(rnorm(n * 20), nrow = n)
print(microbenchmark(c1 <- test(Delta, delta, rx), times = 500))
print(microbenchmark(c2 <- rcpp_test(Delta, delta, rx), times = 500))
identical(c1, c2)
list(c1 = c1, c2 = c2)
}
R реализация:
test <- function(Delta, delta, rx){
const <- list()
for(i in 1:ncol(delta)){
const[[i]] <- rx * (Delta / (1 + delta[, i]))
}
const
}
Реализация Rcpp:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List rcpp_test(NumericVector Delta,
NumericMatrix delta,
NumericMatrix rx) {
int n = Delta.length();
int m = rx.ncol();
List c;
NumericMatrix c1;
for(int i = 0; i < delta.ncol(); ++i){
c1 = NumericMatrix(n, m);
for(int k = 0; k < n; ++k){
double tmp = Delta[k] / (1 + delta(k, i));
for(int j = 0; j < c1.ncol(); ++j){
c1(k, j) = rx(k, j) * tmp;
}
}
c.push_back(c1);
}
return c;
}
Я понимаю, что нет гарантии повышения эффективности с помощью Rcpp, но, учитывая простой пример, который я показываю здесь, я не понимаю, почему код Rcpp работает так медленно.
Unit: milliseconds
expr min lq mean median uq max neval
c1 <- test(Delta, delta, rx) 13.16935 14.19951 44.08641 30.43126 73.78581 115.9645 500
Unit: milliseconds
expr min lq mean median uq max neval
c2 <- rcpp_test(Delta, delta, rx) 143.1917 158.7481 171.6116 163.413 173.7677 247.5495 500
В идеале rx
- это список матриц в моем проекте. Переменная i
в цикле for будет использоваться для выбора элемента для вычислений. Сначала я подозревал, что передача List
в Rcpp может иметь большие накладные расходы, поэтому в этом примере я предположил, что rx
является фиксированной матрицей, используемой для всех i
. Похоже, что это не причина медлительности.