6

是否可以在与 R 并行的单个多核机器上迭代单个文本文件?对于上下文,文本文件介于 250-400MB 的 JSON 输出之间。

编辑:

这是我一直在玩的一些代码示例。令我惊讶的是,并行处理并没有获胜——只是基本的 lapply——但这可能是由于我的用户错误。此外,当我试图读取大量大文件时,我的机器卡住了。

## test on first 100 rows of 1 twitter file
library(rjson)
library(parallel)
library(foreach)
library(plyr)
N = 100
library(rbenchmark)
mc.cores <- detectCores()
benchmark(lapply(readLines(FILE, n=N, warn=FALSE), fromJSON),
          llply(readLines(FILE, n=N, warn=FALSE), fromJSON),
          mclapply(readLines(FILE, n=N, warn=FALSE), fromJSON),
          mclapply(readLines(FILE, n=N, warn=FALSE), fromJSON, 
                   mc.cores=mc.cores),
          foreach(x=readLines(FILE, n=N, warn=FALSE)) %do% fromJSON(x),
          replications=100)

这是第二个代码示例

parseData <- function(x) {
  x <- tryCatch(fromJSON(x), 
                error=function(e) return(list())
                )
  ## need to do a test to see if valid data, if so ,save out the files
  if (!is.null(x$id_str)) {
    x$created_at <- strptime(x$created_at,"%a %b %e %H:%M:%S %z %Y")
    fname <- paste("rdata/",
                   format(x$created_at, "%m"),
                   format(x$created_at, "%d"),
                   format(x$created_at, "%Y"),
                   "_",
                   x$id_str,
                   sep="")
    saveRDS(x, fname)
    rm(x, fname)
    gc(verbose=FALSE)
  }
}

t3 <- system.time(lapply(readLines(FILES[1], n=-1, warn=FALSE), parseData))
4

2 回答 2

7

答案取决于实际问题是什么:并行读取文件,或并行处理文件。

并行阅读

您可以将 JSON 文件拆分为多个输入文件并并行读取它们,例如使用plyr与并行后端相结合的函数:

result = ldply(list.files(pattern = ".json"), readJSON, .parallel = TRUE)

注册后端可能可以使用parallel现在集成在基础 R 中的包来完成。或者您可以使用该doSNOW包,有关详细信息,请参阅我的博客上的这篇文章

并行处理

在这种情况下,最好的办法是将整个数据集读入字符向量,拆分数据,然后使用并行后端与plyr函数等结合。

于 2012-11-26T19:20:04.240 回答
2

readLines()由于非并行文件系统 IO 的性质,可能不会。当然,如果您使用并行 NFS 或类似 HDFS 的东西,则此限制将不适用。readLine()但是假设您使用的是“标准”架构,那么并行化您的调用是不可行的。

您最好的选择可能是读入整个文件,因为 <500MB 可能适合内存,然后在您已经读入对象后并行处理。

于 2012-11-26T19:14:26.563 回答