Moh*_*sri 4 performance r matrix sparse-matrix
这是一个比较使用Matrix 包和常规R 基矩阵类从大型稀疏矩阵和密集矩阵中提取行的示例。
对于稠密矩阵,基类的速度几乎快 395 倍matrix:
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
Run Code Online (Sandbox Code Playgroud)
对于稀疏矩阵,又几乎支持了 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
Run Code Online (Sandbox Code Playgroud)
为什么速度存在差异?有没有办法加快Matrix包中的提取速度?
我不知道到底是什么问题,可能是 S4 调度(这可能是像这样的小调用的很大一部分)。matrix通过(1)切换到行主格式和(2)编写我自己的专用访问器函数,我能够获得相当于(这有一个非常简单的工作,索引+访问连续的内存块)的性能。我不知道你到底想做什么,也不知道是否值得这么麻烦......
设置示例:
\n\nset.seed(101)\nS1 <- matrix(1*(runif(2000^2)<0.1), 2000, 2000)\nRun Code Online (Sandbox Code Playgroud)\n\n转换为列优先 ( dgCMatrix) 和行优先 ( dgRMatrix) 形式:
library(Matrix)\nS2C <- Matrix(S1, sparse = TRUE)\nS2R <- as(S1,"dgRMatrix")\nRun Code Online (Sandbox Code Playgroud)\n\n自定义访问器:
\n\nmy_row_extract <- function(m,i=1) {\n r <- numeric(ncol(m)) ## set up zero vector for results\n ## suggested by @OttToomet, handles empty rows\n inds <- seq(from=m@p[i]+1, \n to=m@p[i+1], length.out=max(0, m@p[i+1] - m@p[i]))\n r[m@j[inds]+1] <- m@x[inds] ## set values\n return(r)\n}\nRun Code Online (Sandbox Code Playgroud)\n\n检查方法之间结果的相等性(全部TRUE):
all.equal(S2C[1,],S1[1,])\nall.equal(S2C[1,],S2R[1,])\nall.equal(my_row_extract(S2R,1),S2R[1,])\nall.equal(my_row_extract(S2R,17),S2R[17,])\nRun Code Online (Sandbox Code Playgroud)\n\n基准:
\n\nbenchmark(S1[1,], S2C[1,], S2R[1,], my_row_extract(S2R,1),\n columns=c("test","elapsed","relative"))\n## test elapsed relative\n## 4 my_row_extract(S2R, 1) 0.015 1.154\n## 1 S1[1, ] 0.013 1.000\n## 2 S2C[1, ] 0.563 43.308\n## 3 S2R[1, ] 4.113 316.385\nRun Code Online (Sandbox Code Playgroud)\n\n专用提取器与基础基质具有竞争力。S2R即使对于行提取也非常慢(令人惊讶);然而,?"dgRMatrix-class"确实说
\n\n注意:面向列的稀疏类,例如\xe2\x80\x98dgCMatrix\xe2\x80\x99,是首选,并且在\xe2\x80\x98Matrix\xe2\x80\x99 包中得到更好的支持。
\n
| 归档时间: |
|
| 查看次数: |
384 次 |
| 最近记录: |