2017-02-17 9 views
-1

Я начинаю с Rcpp. В настоящее время я написал код Rcpp, который был применен к двум 3-мерным массивам: Array1 и Array2. Предположим, что Array1 имеет размерность (1000, 100, 40) и Array2 имеет размерность (1000, 96, 40).Эффективность программирования Rcpp

Я хотел бы выполнить wilcox.test с помощью:

wilcox.test(Array1[i, j,], Array2[i,,]) 

В R, я написал вложенный for петли, которые завершили расчет примерно через полчаса.

Затем я написал его в Rcpp. Расчет в Rcpp потребовал часа для достижения тех же результатов. Я думал, что это должно быть быстрее, поскольку он написан на языке C++. Я предполагаю, что мой стиль кодирования является причиной низкой эффективности.

Следующий мой код Rcpp, не могли бы вы помочь мне узнать, какое улучшение я должен сделать, пожалуйста? Я ценю это!

// [[Rcpp::depends(RcppArmadillo)]] 
#include <RcppArmadillo.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
NumericVector Cal(NumericVector Array1,NumericVector Array2,Function wilc) { 

    NumericVector vecArray1(Array1); 
    IntegerVector arrayDims1 = vecArray1.attr("dim"); 

    NumericVector vecArray2(Array2); 
    IntegerVector arrayDims2 = vecArray2.attr("dim"); 

    arma::cube cubeArray1(vecArray1.begin(), arrayDims1[0], arrayDims1[1],  arrayDims1[2], false); 

    arma::cube cubeArray2(vecArray2.begin(), arrayDims2[0], arrayDims2[1], arrayDims2[2], false); 

    arma::mat STORE=arma::mat(arrayDims1[0], arrayDims1[1]); 

    for(int i=0;i<arrayDims1[1];i++) 
    { 

    for(int j=0;j<arrayDims1[0];j++){ 
     arma::vec  v_cl=cubeArray1.subcube(arma::span(j),arma::span(i),arma::span::all); 

     //arma::mat  tem=cubeArray2.subcube(arma::span(j),arma::span::all,arma::span::all); 

     //arma::vec v_ct=arma::vectorise(tem); 

     arma::vec v_ct=arma::vectorise(cubeArray2.subcube(arma::span(j),arma::span::all,arma::span::all)); 

     Rcpp::List resu=wilc(v_cl,v_ct); 
     STORE(j,i)=resu[2]; 

    } 

    } 


    return(Rcpp::wrap(STORE)); 

} 

Функция wilc будет wilcox.test от R.

Ниже приводится часть моего R кода для реализации вышеупомянутой идеи, где CELLS и CTRLS два 3D-массива в R.

for(i in 1:ncol(CELLS)) { 
    if(T){ print(i) } 
    for (j in 1:dim(CELLS)[1]) { 
    wtest = wilcox.test(CELLS[j,i,], CTRLS[j,,]) 
    TSTAT_clcl[j,i] = wtest$p.value 
    } 
} 
+0

Вызов R из C++ внутри каждого цикла ... в значительной степени совпадает с записью в R. У вас было неправильное исходное предположение: петли, которые вы переписали, не были узким местом. В следующий раз, возможно, сначала профиль. –

+0

Привет @DirkEddelbuettel, спасибо за ваш комментарий! Я переписал его в R, используя foreach, и использовал doSNOW для реализации кода параллельно. Теперь, учитывая массив 1000 * 100 * 40, для получения результата требуется 18 минут. Однако это все еще не идеально. Это очень сложная задача для тех, кому не хватает знаний в области компьютерных наук, таких как я, чтобы попытаться улучшить производительность кода. Во всяком случае, я считаю это интересным! –

ответ

1

Затем я написал ее в Rcpp. Расчет в Rcpp потребовал часа для достижения тех же результатов. Я думал, что это должно быть быстрее, поскольку он написан на языке C++.

Необходимая оговорка:

Встраивание R код C++ и ожидает увеличения скорости игры глупца. Вам необходимо будет переписать wilcox.test в C++ вместо звонка R. В противном случае вы теряете все преимущества, которые вы получаете.

В частности, я написал в post, иллюстрирующий эту загадку в отношении с использованием diff функции в R. В статье я подробно сравнивая реализацию чистогоС ++, реализация С ++ с использованием функции R в подпрограмме, и чистую реализацию R. Кража microbenchmark иллюстрирует вышеупомянутую проблему.

expr  min  lq  mean  median uq  max   neval 
arma_fun 26.117 27.318 37.54248 28.218 29.869 751.087  100 
r_fun  127.883 134.187 212.81091 138.390 151.148 1012.856 100 
rcpp_fun 250.663 265.972 356.10870 274.228 293.590 1430.426 100 

Таким образом, чистая реализацияC++ имел самую большую скорость вверх.

Следовательно, заберите это необходимость перевести кода подпрограммы wilcox.testR к чистой реализации C++ уронить время работы. В противном случае, это не имеет смысла писать код в C++, так как компонент C++ должен остановить и ждать результатов от R перед продолжением. У этого традиционно есть лот накладных расходов, чтобы обеспечить надежную защиту данных.

+0

Большое вам спасибо! Я нашел тест подписи Wilcoxon, реализованный в C++ [ALGLIB] (http://www.alglib.net/hypothesistesting/wilcoxonsignedrank.php). Могу ли я узнать ваше мнение об этом? Стоит попробовать? Я ценю это. –

+0

В настоящее время нет оболочки для использования ALGLIB в экосистеме _R_. (c.f. http://stackoverflow.com/questions/27775923/is-it-possible-to-use-alglib-with-rcpp) Вам, скорее всего, придется реализовать его самостоятельно. – coatless

+0

Плохая новость. В любом случае, спасибо вам большое! Я первый раз задаю вопрос на этом веб-сайте, я не ожидал, что смогу получить обратную связь так быстро, спасибо @coatless! –

 Смежные вопросы

  • Нет связанных вопросов^_^