내 예제에서 Rcpp 구현이 R 함수보다 훨씬 느린 이유는 무엇입니까?

한 장

C ++ 및 R에 대한 경험이 있지만 Rcpp의 초보자입니다. 최근에 저는 이전 프로젝트에서 Rcpp를 사용하여 큰 성공을 거두었으므로 새로운 프로젝트에 적용하기로 결정했습니다. 내 Rcpp 코드가 해당 R 함수보다 훨씬 느릴 수 있다는 사실에 놀랐습니다. 이유를 파악하기 위해 R 기능을 단순화하려고 시도했지만 단서를 찾을 수 없습니다. 귀하의 도움과 의견을 환영합니다!

R 및 Rcpp 구현을 비교하는 주요 R 함수 :

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는 내 프로젝트의 행렬 목록입니다. ifor 루프 의 변수 는 계산할 요소를 선택하는 데 사용됩니다. 처음에는 a List를 Rcpp에 전달하는 것이 높은 오버 헤드를 가질 수 있다고 생각했기 때문에이 예제에서는 rx모든 .NET 에 사용되는 고정 행렬 이라고 가정 했습니다 i. 그것이 느린 이유가 아닌 것 같습니다.

랄프 스 튜너

귀하의 R 코드는 다소 최적 인 것 같습니다. 즉, 모든 실제 작업은 컴파일 된 코드에서 수행됩니다. C ++ 코드의 경우 내가 찾을 수있는 주요 문제 c1.ncol()는 타이트 루프에서 호출 하는 것입니다. 내가 가진 것을 교체하는 경우 m내가 믹스에 RcppArmadillo을 추가하면 C ++ 솔루션은 거의 빨리 R.으로, 나는 매우 컴팩트 한 구문을 얻을 수 있지만 빠른 순수 Rcpp의 코드보다. 나에게 이것은 잘 작성된 R 코드를이기는 것이 정말 어려울 수 있음을 보여줍니다.

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

// [[Rcpp::export]]
List arma_test(const arma::vec& Delta,
           const arma::mat& delta,
           const arma::mat& rx) {
  int l = delta.n_cols;
  List c(l);

  for (int i = 0; i < l; ++i) {
    c(i) = rx.each_col() % (Delta / (1 + delta.col(i)));
  }

  return c;  
}

// [[Rcpp::export]]
List rcpp_test(NumericVector Delta, 
               NumericMatrix delta, 
               NumericMatrix rx) {

  int n = Delta.length();
  int m = rx.ncol();

  List c(delta.ncol()); 
  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 < m; ++j){
        c1(k, j) = rx(k, j) * tmp; 
      }
    }
    c(i) = c1;
  }

  return c;

}

/*** R
test <- function(Delta, delta, rx){

  const <- list()
  for(i in 1:ncol(delta)){
    const[[i]] <- rx * (Delta / (1 + delta[, i]))
  }

  const

}

n <- 50000
Delta <- exp(rnorm(n))
delta <- exp(matrix(rnorm(n * 5), nrow = n))
rx <- matrix(rnorm(n * 20), nrow = n)
bench::mark(test(Delta, delta, rx),
            arma_test(Delta, delta, rx),
            rcpp_test(Delta, delta, rx))
 */

산출:

# A tibble: 3 x 14
  expression     min    mean  median     max `itr/sec` mem_alloc  n_gc n_itr
  <chr>      <bch:t> <bch:t> <bch:t> <bch:t>     <dbl> <bch:byt> <dbl> <int>
1 test(Delt…  84.3ms  85.2ms  84.9ms  86.6ms     11.7     44.9MB     2     4
2 arma_test… 106.5ms 107.7ms 107.7ms 108.9ms      9.28    38.1MB     3     2
3 rcpp_test… 101.9ms 103.2ms 102.2ms 106.6ms      9.69    38.1MB     1     4
# … with 5 more variables: total_time <bch:tm>, result <list>, memory <list>,
#   time <list>, gc <list>

또한 출력 목록을를 피하는 필수 크기로 명시 적으로 초기화 push_back했지만 큰 차이는 없습니다. Rcpp의 데이터 구조와 같은 벡터를 사용하면 벡터 push_back를 확장 할 때마다 복사본이 만들어 지므로 사용을 피해야 합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

내 Spark DataFrame이 RDD보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Mac에서 SDL이 Linux보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

내 awk 스크립트가 head + tail 스크립트보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Windows에서 Qt 5.3을 디버깅하는 것이 Ubuntu보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

큰 목록에서`filterM + mapM_`이`mapM_ + when`보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

MySQL에서 WHERE 절을 사용하여 SELECT COUNT (*)가 SELECT보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

igraph의 cliques () 메서드가 JustTheCliques보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

이 정렬 알고리즘 구현에서 벡터가 배열보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

ExpandoObject가 Dictionary보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Airflow 1.10.12가 1.10.10보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

mb_strpos ()가 strpos ()보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

strcmp가 내 함수보다 훨씬 빠른 이유는 무엇입니까?

분류에서Dev

short 기본 유형이 long 또는 int보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

목록을 반복하는 것이 파이썬에서 반복을 반복하는 것보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

목록을 반복하는 것이 파이썬에서 반복을 반복하는 것보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

이 jQuery 코드가이 코드보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

이 SBV / Z3 코드에서 Int32 정렬이 Integer 정렬보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

VC2010에서 "디버깅 시작"이 "처리에 연결"보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Linux의 RDP 클라이언트가 Windows보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Linux의 RDP 클라이언트가 Windows보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

USB 플래시 드라이브가 SSD보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

vim 검색이 "cat fileName | grep targetText"보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

stoi가 -O3가없는 stringstream보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Node JS에서 Mysql 쿼리 실행이 직접 Mysql 쿼리 실행보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

이 부분 빠른 정렬 구현이 표준 라이브러리 정렬보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

openmp 32 스레드가 1 스레드보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

Python Lambda가 동일한 기능을 가진 Javascript Lambda보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

MEX 코드가 MATLAB 코드보다 훨씬 느린 이유는 무엇입니까?

분류에서Dev

내 코드가 예상보다 훨씬 더 많이 실행되는 이유는 무엇입니까?

Related 관련 기사

  1. 1

    내 Spark DataFrame이 RDD보다 훨씬 느린 이유는 무엇입니까?

  2. 2

    Mac에서 SDL이 Linux보다 훨씬 느린 이유는 무엇입니까?

  3. 3

    내 awk 스크립트가 head + tail 스크립트보다 훨씬 느린 이유는 무엇입니까?

  4. 4

    Windows에서 Qt 5.3을 디버깅하는 것이 Ubuntu보다 훨씬 느린 이유는 무엇입니까?

  5. 5

    큰 목록에서`filterM + mapM_`이`mapM_ + when`보다 훨씬 느린 이유는 무엇입니까?

  6. 6

    MySQL에서 WHERE 절을 사용하여 SELECT COUNT (*)가 SELECT보다 훨씬 느린 이유는 무엇입니까?

  7. 7

    igraph의 cliques () 메서드가 JustTheCliques보다 훨씬 느린 이유는 무엇입니까?

  8. 8

    이 정렬 알고리즘 구현에서 벡터가 배열보다 훨씬 느린 이유는 무엇입니까?

  9. 9

    ExpandoObject가 Dictionary보다 훨씬 느린 이유는 무엇입니까?

  10. 10

    Airflow 1.10.12가 1.10.10보다 훨씬 느린 이유는 무엇입니까?

  11. 11

    mb_strpos ()가 strpos ()보다 훨씬 느린 이유는 무엇입니까?

  12. 12

    strcmp가 내 함수보다 훨씬 빠른 이유는 무엇입니까?

  13. 13

    short 기본 유형이 long 또는 int보다 훨씬 느린 이유는 무엇입니까?

  14. 14

    목록을 반복하는 것이 파이썬에서 반복을 반복하는 것보다 훨씬 느린 이유는 무엇입니까?

  15. 15

    목록을 반복하는 것이 파이썬에서 반복을 반복하는 것보다 훨씬 느린 이유는 무엇입니까?

  16. 16

    이 jQuery 코드가이 코드보다 훨씬 느린 이유는 무엇입니까?

  17. 17

    이 SBV / Z3 코드에서 Int32 정렬이 Integer 정렬보다 훨씬 느린 이유는 무엇입니까?

  18. 18

    VC2010에서 "디버깅 시작"이 "처리에 연결"보다 훨씬 느린 이유는 무엇입니까?

  19. 19

    Linux의 RDP 클라이언트가 Windows보다 훨씬 느린 이유는 무엇입니까?

  20. 20

    Linux의 RDP 클라이언트가 Windows보다 훨씬 느린 이유는 무엇입니까?

  21. 21

    USB 플래시 드라이브가 SSD보다 훨씬 느린 이유는 무엇입니까?

  22. 22

    vim 검색이 "cat fileName | grep targetText"보다 훨씬 느린 이유는 무엇입니까?

  23. 23

    stoi가 -O3가없는 stringstream보다 훨씬 느린 이유는 무엇입니까?

  24. 24

    Node JS에서 Mysql 쿼리 실행이 직접 Mysql 쿼리 실행보다 훨씬 느린 이유는 무엇입니까?

  25. 25

    이 부분 빠른 정렬 구현이 표준 라이브러리 정렬보다 훨씬 느린 이유는 무엇입니까?

  26. 26

    openmp 32 스레드가 1 스레드보다 훨씬 느린 이유는 무엇입니까?

  27. 27

    Python Lambda가 동일한 기능을 가진 Javascript Lambda보다 훨씬 느린 이유는 무엇입니까?

  28. 28

    MEX 코드가 MATLAB 코드보다 훨씬 느린 이유는 무엇입니까?

  29. 29

    내 코드가 예상보다 훨씬 더 많이 실행되는 이유는 무엇입니까?

뜨겁다태그

보관