2

私は自分の目的に完全に機能するコードを持っています(特定のパターンでいくつかのファイルを読み取り、各ファイル内の行列を読み取り、各ファイルペアを使用して何かを計算します...最終的な出力は、ファイルの同じサイズの行列です番号)そしてこのように見えます:

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のループを意味します)。並列化したいのですが、助けが必要です!あなたの親切な提案を待っています!

前もって感謝します!

Gab

4

1 に答える 1

4

ボトルネックはおそらくディスクからの読み取りです。コードを並行して実行しても、処理が高速になるとは限りません。この場合、同じディスクから同時に読み取ろうとする複数のプロセスは、単一のプロセスよりもさらに遅くなる可能性があります。

行列は別のRプロセスによって書き込まれているため、実際にはRのバイナリ形式で保存する必要があります。すべてのマトリックスを1回だけ読み取るため、プログラムを高速化する唯一の方法は、ディスクからの読み取りを高速化することです。

これがどれだけ速くなるかを示す例です:

# 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のバイナリ形式で保存されたファイルを使用してそのコードを再実行しましょう。

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
于 2013-02-08T16:59:04.167 に答える