私はScalaの遅延イテレータを使用しています。問題が発生しました。その後、私は何をしようとしている大きなファイルに読み込まれ、変換を行い、その結果書き出す:Scala Infinite Iterator OutOfMemory
object FileProcessor {
def main(args: Array[String]) {
val inSource = Source.fromFile("in.txt")
val outSource = new PrintWriter("out.txt")
try {
// this "basic" lazy iterator works fine
// val iterator = inSource.getLines
// ...but this one, which incorporates my process method,
// throws OutOfMemoryExceptions
val iterator = process(inSource.getLines.toSeq).iterator
while(iterator.hasNext) outSource.println(iterator.next)
} finally {
inSource.close()
outSource.close()
}
}
// processing in this case just means upper-cases every line
private def process(contents: Seq[String]) = contents.map(_.toUpperCase)
}
は、だから私は大きなファイルでのOutOfMemoryExceptionを取得しています。ストリームの頭を参照している場合は、Scalaの怠惰なストリームに遭遇する可能性があることはわかっています。ですから、この場合、process()の結果をイテレータに変換し、最初に返すSeqをスローアウェイしてください。
これがまだO(n)のメモリ消費を引き起こす理由は誰にも分かりますか?ありがとう!
更新
はFGEとhuynhjlに応じて、犯人かもしれない配列のように思えるが、私はなぜ知りません。例として、次のコードはうまく動作します(そして、私はSeqを使用しています)。
FGEで示唆したようobject FileReader {
def main(args: Array[String]) {
val inSource = Source.fromFile("in.txt")
val outSource = new PrintWriter("out.txt")
try {
writeToFile(outSource, process(inSource.getLines.toSeq))
} finally {
inSource.close()
outSource.close()
}
}
@scala.annotation.tailrec
private def writeToFile(outSource: PrintWriter, contents: Seq[String]) {
if (! contents.isEmpty) {
outSource.println(contents.head)
writeToFile(outSource, contents.tail)
}
}
private def process(contents: Seq[String]) = contents.map(_.toUpperCase)
野生の推測: '.getLines.toSeq'? – fge