3

我有一个相当大的文件(20-30 Mb)。我有一个映射,其中有一个键和相应的正则表达式作为值,我需要在文件中 grep 以获取键的实际值并将新键、值存储在新映射中。所以这是我的方法

contextmap //initial map which contains key and value in form of regex
contextstrings // final map supposed to have value after the grep

def fgrepFuture(e: (String,String)) = Future { 
val re = new Regex(e._2)
Source.fromFile(f).getLines.foreach {

re findFirstMatchIn _ match {
case None => ("","")
case Some(x) =>(e._1,x.group(1))
}
                                                        }
}
val fg = Future.traverse(tmpmap)(fgrepFuture)
fg onComplete{
case tups => for(t <- tups) contextstrings += (t.toString.split(",").head -> t.toString.split(",").tail.head)
}

这里的问题是,当未来完成我的其余代码(基于 akka 演员的异步模型)时,我没有快速获得文件中的 grepped 值(我希望在全球范围内可用) .我需要快速获得价值,我不知道为什么这种方法没有给我(因为多个未来并行工作),所以请指出缺陷。另外,如果有更好的方法来获得多个价值从一个相当大的文件中提取,请也提出建议。

4

2 回答 2

2

您可以确定程序中的最远点,如果到达并且功能不完整,则需要使用 await,但您可以同时做一些工作的好处有限。您可以做的其他事情是尝试以这样的并行方式进行 grep。

val chunkSize = 128 * 1024
val iterator = Source.fromFile(path).getLines.grouped(chunkSize)
iterator.foreach { lines => 
    lines.par.foreach { line => process(line) }
}

基于这篇文章

于 2013-11-14T14:09:08.160 回答
1

您可能正在做并行工作,但似乎所有并行任务都在读取同一个文件,f. 这显然会非常慢......甚至比只读取一次文件还要慢。

IO 总是一个瓶颈,并行性对此无能为力。

您可以:

1)只需对文件进行一次传递并抓住该单次传递中的所有键。

2)将文件加载到内存中,然后让并行任务在该只读数据结构上工作。

如果每个任务都完成了很多工作,选项 2) 会很有用,但是由于您只是在 grepping,所以我会选择选项 1)。

于 2013-11-14T16:47:52.327 回答