Conversion von R-Matrizen zu Gürteltier ist sehr langsam
Eine Beobachtun
Für mittelgroße Matrizen sind die Overheads beim Übertragen von Matrizen von R nach C ++ für @ massiv langsamearma::mat
Typen als fürNumericMatrix
Typen. Zum Beispiel 250x so lange. Hier ist ein minimales Beispiel
#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 ;
}
Then, in 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
So nur eine Matrix als @ übergebarma::mat
type ist ungefähr 250x langsamer alsNumericMatrix
. Das ist verrückt! So..
Fragen entstehen
Was ist los? Warum istmat
s viel langsamer alsNumericMatrix
?ibt es eine gute Möglichkeit, damit umzugehen? Ich habe ein Problem, bei dem ich ein @ verwenden musarma::mat
für eine ziemlich einfache Matrixalgebra in einer Funktion, die oft aufgerufen wird. Ich benutze geradearma
wird durchgehend eingegeben und mein Code lautetvie langsamer als ich erwartet hatte (so kam es, dass ich die dummen Beispiele oben auskochte). Eine Geschwindigkeitsstrafe von 250x ist eine so große Sache, dass ich große Teile des Codes neu schreiben werde, um @ zu verwendeNumericMatrix
Typen überall. Tatsächlich könnte ich am Ende meine eigene Matrixmultiplikationsfunktion für @ schreibeNumericMatrix
und aufgebenarma
Typen insgesamt. Aber bevor ich es tue, gibt es bessere Lösungen? (Obwohl ich eine andere Art zu lesen vermute, ist dies nicht dasarma::mat
ist langsam von R-Typen zu konvertieren, aber dasNumericMatrix
type ist unglaublich effizient!)