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 アクターの非同期モデルに基づく) を完了するまでに先に進みすぎて、ファイルから grep された値をすぐに取得できないことです (グローバルに利用できるようにしたい)。 .私は値を速く取得する必要がありますが、なぜこのアプローチが私に与えないのか分かりません(複数の未来が並行して動作するため)ので、欠陥を指摘してください.また、複数の値を取得するためのより良いアプローチがある場合かなり大きなファイルからgrepさ​​れたことも提案してください。

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) ファイルに対して 1 回のパスを実行し、その 1 回のパスですべてのキーを取得します。

2) ファイルをメモリにロードし、その読み取り専用データ構造で並列タスクを実行します。

オプション 2) は、各タスクで多くの作業が行われる場合に便利ですが、grep を行うだけなので、オプション 1) を使用します。

于 2013-11-14T16:47:52.327 に答える