2

何千ものファイル (50K) があり、各ファイルには約 10K 行あります。ファイルを読み込んで処理を行い、その行を出力ファイルに書き戻します。私の読み取りと処理ははるかに高速ですが、文字列イテレーターを単一の文字列に変換してファイルに書き込む最後のステップには長い時間がかかります (ほぼ 1 秒です。全体でこれを行うための計算は行いません)。ファイルの数は約 50K です)。これが、解析時間を改善する上でのボトルネックであることがわかります。

これは私のコードです。

var processedLines = linesFromGzip(new File(fileName)).map(line => MyFunction(line))
var  outFile = Resource.fromFile(outFileName)

outFile.write(processedLines.mkString("\n"))  // severe overhead caused by this line-> processedLines.mkString("\n")

(他のいくつかのフォーラム/ブログで、mkString が他のアプローチよりもはるかに優れていることを読みました。 (例)

mkString("\n") のより良い代替手段はありますか? ファイルの処理速度を向上させるまったく異なるアプローチはありますか。(覚えておいてください、私はそれぞれ10K行に近い50Kファイルを持っています)。

4

2 に答える 2

1

を使用しているため、書き込みが遅くなりますIteratorIterators は遅延評価されます。実は遅いのはあなたの書き込みではなく、 の評価ですIteraor。AnIteratorは遅延評価されます。これは、使用した瞬間に評価されることを意味します。の要素をマッピングしているため、まだ評価されていないIteratornew が生成されます。Iteratorを呼び出した瞬間に評価されますmkString。この関数は、RAM に保存される にIterator変換します。これを回避するには、 Jatin が提案Stringするように、を受け入れる書き込み関数を使用することをお勧めします。Iterator彼のコードを次のように書き換えることができます。

processedLines.foreach(line => {
  outfile.write(line)
  outfile.write("\n")
}

これは実際には に対する操作Iteratorです。一度に 1 行ずつ評価して書き込みます。

于 2013-11-06T07:14:37.347 に答える