并行化并加速R代码以读入许多文件

时间:2013-02-05 17:22:18

标签: r performance file-io parallel-processing

我的代码完全符合我的目的(它读取一些具有特定模式的文件,读取每个文件中的矩阵并使用每个文件对计算一些内容...最终输出是一个具有相同大小的矩阵文件号)并且看起来像这样:

m<- 100
output<- matrix(0, m, m)

lista<- list.files(pattern = "q")
listan<- as.matrix(lista)
n <- nrow(listan)

for (i in 1:n) {    
AA    <- read.table((listan[i,]), header = FALSE)
A<- as.matrix(AA)
dVarX <- sqrt(mean(A * A))

 for (j in i:n) {
    BB <- read.table ((listan[j,]), header = FALSE)
    B<- as.matrix(BB)
    V <- sqrt (dVarX * (sqrt(mean(B * B))))
    output[i,j] <- (sqrt(mean(A * B))) / V        
 }
}

我的问题是需要花费很多时间(我有大约5000个矩阵,这意味着5000x5000循环)。 我想并行化,但我需要一些帮助! 等待你的建议!

提前谢谢!

加布

1 个答案:

答案 0 :(得分:4)

瓶颈可能是从磁盘读取的。并行运行代码并不能保证更快。在这种情况下,尝试同时从同一磁盘读取的多个进程可能比单个进程更慢。

由于你的矩阵是由另一个R进程编写的,你真的应该用R的二进制格式保存它们。您只需一次读取每个矩阵,因此使程序更快的唯一方法是更快地从磁盘读取。

以下是一个示例,向您展示它可以更快的速度:

# make some random data and write it to disk
set.seed(21)
for(i in 0:9) {
  m <- matrix(runif(700*700), 700, 700)
  f <- paste0("f",i)
  write(m, f, 700)              # text format
  saveRDS(m, paste0(f,".rds"))  # binary format
}

# initialize two output objects
m <- 10
o1 <- o2 <- matrix(NA, m, m)

# get list of file names
files <- list.files(pattern="^f[[:digit:]]+$")
n <- length(files)

首先,让我们使用scan运行您的代码,这已经比使用read.table的当前解决方案快得多。

system.time({
  for (i in 1:n) {    
    A <- scan(files[i],quiet=TRUE)

    for (j in i:n) {
      B <- scan(files[j],quiet=TRUE)
      o1[i,j] <- sqrt(mean(A*B)) / sqrt(sqrt(mean(A*A)) * sqrt(mean(B*B)))
    }
  }
})
#    user  system elapsed 
#   31.37    0.78   32.58

现在,让我们使用以R&lt; s二进制格式保存的文件重新运行该代码:

system.time({
  for (i in 1:n) {    
    fA <- paste0(files[i],".rds")
    A <- readRDS(fA)

    for (j in i:n) {
      fB <- paste0(files[j],".rds")
      B <- readRDS(fB)
      o2[i,j] <- sqrt(mean(A*B)) / sqrt(sqrt(mean(A*A)) * sqrt(mean(B*B)))
    }
  }
})
#    user  system elapsed 
#    2.42    0.39    2.92

所以二进制格式快〜10倍!输出是一样的:

all.equal(o1,o2)
# [1] TRUE