簡體   English   中英

在嵌套循環中避免過多的“聲明 Rcpp List 的相同元素”

[英]Avoid too many “declare same elements of Rcpp List” in nested loops

我想問一下如何節省在嵌套循環中訪問 List 的計算時間。 這是一個包含兩個函數的 Rcpp 示例:

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

// [[Rcpp::export]]
void first(const Rcpp::List ETA
          ,const int N
          ,const int I
                      ) {   
    for(int i = 0; i < I; ++i) {
        arma::rowvec eta = ETA[i];
        for(int n = 0; n < N; ++n) {
            // use eta to do some calculation
        }
    }
}

// [[Rcpp::export]]
void second(const Rcpp::List ETA
           ,const int N
           ,const int I
                      ) {   
    for(int n = 0; n < N; ++n) {
        for(int i = 0; i < I; ++i) {
            arma::rowvec eta = ETA[i];
            // use eta to do some calculation
        }
    }
}

比較 R 中的時間:

Rcpp::sourceCpp("test.cpp") # save the above code as "test.cpp"
ETA = list()
N = 10^8
I = 10
for (i in 1:I) ETA[[i]] = rep(0,i) # just an example.
ptm <- proc.time(); first(ETA,N,I); print((proc.time() - ptm))
#    user  system elapsed 
#       0       0       0 
ptm <- proc.time(); second(ETA,N,I); print((proc.time() - ptm))
#    user  system elapsed 
#   16.69    0.00   16.69

這里的ETA是一個列表,其中每個元素可以具有動態長度(向量)或動態維度(矩陣)。 在這段代碼中,第一種方式比第二種方式快得多。 但是對於實際需要,當有其他變量迭代n時,第二種方式可以減少計算時間。

問題:

對於第一種方式或第二種方式,我們可以在循環之外(之前)聲明eta ,以便我們不需要多次聲明相同的eta嗎?

您在每個循環期間都在進行隱式轉換和深層復制,因此編譯器無法優化它也就不足為奇了。

您可以做的是預先計算所有 etas 並將它們存儲在向量中。 (我在循環中填寫了一些工作,因為可以完全優化空循環)。

// [[Rcpp::export]]
double third(const Rcpp::List ETA
              ,const int N
              ,const int I) {   
  double output=0;
  
  // pre-create eta rowvecs
  std::vector<arma::rowvec> eta_vec(Rf_xlength(ETA));
  for(int i = 0; i < I; ++i) {
    eta_vec[i] = arma::rowvec(Rcpp::NumericVector(ETA[i]));
  }
  
  for(int n = 0; n < N; ++n) {
    for(int i = 0; i < I; ++i) {
      output += sum(eta_vec[i]);
    }
  }
  return output;
}

結果:

> ptm <- proc.time(); first(ETA,N,I); print((proc.time() - ptm))
[1] 0
   user  system elapsed 
  2.761   0.000   2.761 
> #    user  system elapsed 
> #       0       0       0 
> ptm <- proc.time(); second(ETA,N,I); print((proc.time() - ptm))
[1] 0
   user  system elapsed 
 29.935   0.000  29.930 
> 
> ptm <- proc.time(); third(ETA,N,I); print((proc.time() - ptm))
[1] 0
   user  system elapsed 
  2.599   0.000   2.598 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM