与常规矩阵类相比,Matrix包中的提取速度非常慢

时间:2017-12-27 18:46:58

标签: r performance matrix sparse-matrix

这是使用Matrix package与常规R base-matrix类比较大型矩阵(稀疏和密集)的行提取的示例。

对于密集矩阵,基类matrix的速度快了近395倍:

library(Matrix)
library(microbenchmark)

## row extraction in dense matrices
D1<-matrix(rnorm(2000^2), 2000, 2000)
D2<-Matrix(D1)
> microbenchmark(D1[1,], D2[1,])
Unit: microseconds
    expr      min        lq       mean    median       uq      max neval
 D1[1, ]   14.437   15.9205   31.72903   31.4835   46.907   75.101   100
 D2[1, ] 5730.730 5744.0130 5905.11338 5777.3570 5851.083 7447.118   100

对于稀疏矩阵,它几乎是63次,再次支持matrix

## row extraction in sparse matrices
S1<-matrix(1*(runif(2000^2)<0.1), 2000, 2000)
S2<-Matrix(S1, sparse = TRUE)
microbenchmark(S1[1,], S2[1,])
Unit: microseconds
    expr      min       lq       mean    median        uq      max neval
 S1[1, ]   15.225   16.417   28.15698   17.7655   42.9905   45.692   100
 S2[1, ] 1652.362 1670.507 1771.51695 1774.1180 1787.0410 5241.863   100

为什么速度差异很大,有没有办法加快Matrix包中的提取速度?

1 个答案:

答案 0 :(得分:2)

我不确切地知道问题是什么,可能是S4发送(这可能是这样一个小电话的一大部分)。通过(1)切换到行主格式和(2)编写自己的特殊内容,我能够获得与set.seed(101) S1 <- matrix(1*(runif(2000^2)<0.1), 2000, 2000) 相当的性能(它具有相当简单的工作,索引+访问连续的内存块)。目的访问者功能。我不确切地知道你想做什么或者是否值得这么麻烦......

设置示例:

dgCMatrix

转换为专栏(dgRMatrix)和行专业(library(Matrix) S2C <- Matrix(S1, sparse = TRUE) S2R <- as(S1,"dgRMatrix") )表格:

my_row_extract <- function(m,i=1) {
    r <- numeric(ncol(m))   ## set up zero vector for results
    inds <- seq(m@p[i]+1,m@p[i+1])  ## find indices
    r[m@j[inds]+1] <- m@x[inds]     ## set values
    return(r)
}

自定义访问者:

TRUE

检查方法之间的结果是否相等(所有all.equal(S2C[1,],S1[1,]) all.equal(S2C[1,],S2R[1,]) all.equal(my_row_extract(S2R,1),S2R[1,]) all.equal(my_row_extract(S2R,17),S2R[17,]) ):

benchmark(S1[1,], S2C[1,], S2R[1,], my_row_extract(S2R,1),
          columns=c("test","elapsed","relative"))
##                     test elapsed relative
## 4 my_row_extract(S2R, 1)   0.015    1.154
## 1                S1[1, ]   0.013    1.000
## 2               S2C[1, ]   0.563   43.308
## 3               S2R[1, ]   4.113  316.385

基准:

S2R

专用提取器与基础矩阵竞争。 ?"dgRMatrix-class"速度超慢,即使是行提取(令人惊讶);但是,angular.module('yourMoudule', ['angularjs-dropdown-multiselect']) 确实说

  

注意:面向列的稀疏类(例如'dgCMatrix')是首选,并且在'Matrix'包中得到更好的支持。