Преобразование матриц R в armadillo очень медленно

Наблюдение

для матриц среднего размера накладные расходы на передачу матриц из R в C++ значительно медленнее для arma::mat типы, чем для NumericMatrix типы. Как принимать вокруг 250x как длиной. Вот минимальный пример

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

// [[Rcpp::export]]
double test_nm( NumericMatrix X ) {
  return 0.0 ;
}

// [[Rcpp::export]]
double test_arma( mat X ) {
  return 0.0 ;
}

// [[Rcpp::export]]
double test_nm_conv( NumericMatrix X ) {
  mat X_arma = as<mat>( X ) ; 
  return 0.0 ;
}

затем, в R:

XX <- matrix( runif( 10000 ), 2000, 50 )
microbenchmark( test_nm( XX ), test_arma( XX ), ( XX ) )

Unit: microseconds
               expr      min       lq      mean   median       uq      max neval
        test_nm(XX)    5.541   16.154   16.0781   17.577   18.876   48.024   100
      test_arma(XX) 1280.946 1337.706 1404.0824 1361.237 1389.476 3385.868   100
   test_nm_conv(XX) 1277.417 1338.835 1393.4888 1358.128 1386.101 4355.533   100

так что просто передача матрицы как arma::mat тип около 250x медленнее, чем NumericMatrix. Это безумие! Так...

вопросы встает

  1. что происходит? Почему это mat так гораздо медленнее, чем NumericMatrix?
  2. есть хороший способ справиться с этим? У меня проблема, когда мне нужно использовать arma::mat для некоторых достаточно простой матричной алгебры в функции, которая вызывается много раз. В настоящее время я использую arma типы повсюду, и мой код много медленнее, чем я ожидал (вот как я закончил готовить глупые примеры выше). Ля штраф скорости 250x-это такое большое дело, что я собираюсь переписать большие разделы кода для использования NumericMatrix типы на протяжении. На самом деле, я мог бы написать свою собственную функцию умножения матрицы на NumericMatrix и оставить arma типы в целом. Но прежде чем я это сделаю, есть ли лучшие решения?

(хотя я думаю, что другой способ прочитать это не то, что arma::mat медленно преобразуется из типов R, но это NumericMatrix тип удивительно эффективен!)

1 ответов


Я считаю, что это создает новую матрицу броненосца, а затем копирует содержимое вашей числовой матрицы.

чтобы привести числовую матрицу к типу arma:: mat, вы должны использовать следующее:

// [[Rcpp::export]]
double test_const_arma( const mat& X ) { 
  return 0.0 ;
}

сравнение скорости на моей машине:

microbenchmark( test_const_arma( XX ), test_nm( XX ), test_arma( XX ), test_nm_conv( XX ))
## Unit: microseconds
##                 expr    min     lq     mean  median      uq     max neval
##  test_const_arma(XX)  1.852  2.381  3.69014  2.7885  4.3490  11.994   100
##          test_nm(XX)  1.925  2.455  3.47679  2.8535  3.5195  21.222   100
##        test_arma(XX) 68.593 71.212 83.63055 73.4555 98.8070 278.981   100
##     test_nm_conv(XX) 68.700 70.983 80.55983 73.1705 82.2665 183.484   100