R cpp rowMaxs против matrixStats rowMaxs - PullRequest
5 голосов
/ 13 апреля 2020

Я пытаюсь эффективно вычислить rowMaxs в R cpp. Очень простая реализация -

arma::mat RcppRowmaxs(arma::mat x){  

  int N = x.n_rows;
  arma::mat rm(N,1);

  for(int nn = 0; nn < N; nn++){
      rm(nn) = max(x.row(nn));
  }

  return(rm);
}

, которая прекрасно работает. Однако, сравнивая эту функцию с другими пакетами, оказалось, что другие реализации гораздо более эффективны. В частности, Rfast::rowMaxs более чем в 6 раз быстрее, чем простая реализация R cpp!

Естественно, я пытался имитировать c поведение Rfast. Однако, как новичок в R cpp, я только пытался загрузить Rfast::rowMaxs непосредственно в R cpp, как описано, например, здесь . К сожалению, использование скрипта R cpp для загрузки функции R, которая снова вызывает скрипт R cpp, кажется довольно медленным после моего теста (см. Строку «RfastinR cpp»):

m = matrix(rnorm(1000*1000),1000,1000)

microbenchmark::microbenchmark(

  matrixStats    = matrixStats::rowMaxs(m),
  Rfast          = Rfast::rowMaxs(m,value=T),
  Rcpp           = RcppRowmaxs(m),
  RfastinRcpp    = RfastRcpp(m),
  apply          = apply(m,1,max)

)

Unit: microseconds
        expr       min         lq       mean     median        uq        max neval cld
 matrixStats  1929.570  2042.8975  2232.1980  2086.5180  2175.470   4025.923   100 a  
       Rfast   666.711   727.2245   842.5578   795.2215   891.443   1477.969   100 a  
        Rcpp  5552.216  5825.4855  6186.9850  5997.8295  6373.737   8568.878   100  b 
 RfastinRcpp  7495.042  7931.2480  9471.8453  8382.6350 10659.672  19968.817   100  b 
       apply 12281.758 15145.7495 22015.2798 17202.9730 20310.939 136844.591   100   c

Любой Советы о том, как улучшить производительность в функции, которую я предоставил выше? Я посмотрел на исходный код Rfast и считаю, что этот является правильным файлом. Однако до сих пор мне не удалось найти важные части кода.

Редактировать: теперь пост изменен, чтобы сосредоточиться на Rfast, после ответа Михаила.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Я только что провел несколько экспериментов на своем ноутбуке. У меня 5-летний HP с 2 ядрами intel i5 с частотой 2,3 ГГц. Приложено изображение с моими результатами. Реализация Rfast намного быстрее, чем реализация matrixStats, всегда, и когда матрица становится больше, разница во времени увеличивается.

enter image description here

1 голос
/ 15 апреля 2020
library(Rfast)
library(microbenchmark)
library(matrixStats)

x <- matrnorm(100,100)
microbenchmark(Rfast::rowMaxs(x,value=TRUE), matrixStats::rowMaxs(x),times=10)
Unit: microseconds
                          expr  min   lq   mean median   uq    max neval
Rfast::rowMaxs(x, value = TRUE) 20.5 20.9 242.64  21.50 23.2 2223.8  10
        matrixStats::rowMaxs(x) 43.7 44.7 327.43  46.95 88.2 2776.8  10

x <- matrnorm(1000,1000)
microbenchmark(Rfast::rowMaxs(x,value=TRUE), matrixStats::rowMaxs(x),times=10)
Unit: microseconds
                            expr    min     lq    mean median     uq    max neval
 Rfast::rowMaxs(x, value = TRUE)  799.5  844.0  875.08  858.5  900.3  960.3    10
         matrixStats::rowMaxs(x) 2229.8 2260.8 2303.04 2269.4 2293.3 2607.8    10

x <- matrnorm(10000,10000)
microbenchmark(Rfast::rowMaxs(x,value=TRUE), matrixStats::rowMaxs(x),times=10)
Unit: milliseconds
                            expr      min       lq      mean    median       uq      max neval
 Rfast::rowMaxs(x, value = TRUE)  82.1157  83.4288  85.81769  84.57885  86.2742  93.0031    10
         matrixStats::rowMaxs(x) 216.0003 218.5324 222.46670 221.00330 225.3302 237.7666    10
...