想到我會張貼我想出來的。 cbb
是正在構建的陣列。在這個糟糕的例子中,cbb
逐漸建立爲一個數組,使用abind
。在每個步驟中,cbb
都必須重新評估,因此每個連續步驟都會變慢 - 這是一個成長中的對象。在這個很好的例子中,cbb
被構建爲一個列表,並且每個步驟都會聲明一個新的列表條目。 R不需要每次重新評估現有列表。陣列在末尾與do.call(abind, c(cbb, list(along = 4)))
綁定在一起。
我發現有幫助的一件事是把cat(".")
放在循環中。如果點打印速度變慢,那可能表明物體在不斷增長。舉個很好的例子,點或多或少以恆定的速率打印。這個好例子比糟糕快十倍。
BAD:
cbb <- array(NA, c(N1, N2, N3, 0))
repeat{
sptsnew <- readBin(to.read, "integer", 2L, 4L)
if(identical(sptsnew, integer(0))){cat("\nend of file\n"); break}
... #reading array metadata
cbb <- abind(cbb, array(readBin(to.read, "double", N1*N2*N3, 4L), c(N1, N2, N3, 1)), along = 4)
cat(".")
}
GOOD:
i <- 1
cbb <- list()
repeat{
sptsnew <- readBin(to.read, "integer", 2L, 4L)
if(identical(sptsnew, integer(0))){cat("\nend of file\n"); break}
... #reading array metadata
cbb[[i]] <- array(readBin(to.read, "double", N1*N2*N3, 4L), c(N1, N2, N3, 1))
i <- i + 1
cat(".")
}
cbb <- do.call(abind, c(cbb, list(along = 4)))
據我所知,'for'迴路中的R支持和_can_使用,儘管名聲不好。認爲'sapply'比'for for'循環更快是一種常見的誤解。 – nicola
我的經驗是'for'比'apply'家族慢得多,我試着用'for'來完成這個任務(在我真正瞭解'* apply'之前)。是否有一些技巧可以讓工作更快? – Bazz
'for'的速度並不比'* apply'慢很多。它通常(稍微)比'lapply'和'vapply'慢。根據情況,可能比'sapply'更慢或更快。它通常比'申請'快。這提供了你正確地編寫循環和(比其他更多的事情)避免增長對象和正確預分配。對你的嘗試更詳細,你可能會有幫助。 – nicola