Scala:高效地将字符串迭代器写入文件

3
我有数千个文件(50K),每个文件大约有10K行。我读取文件并进行一些处理,然后将这些行写回输出文件。虽然我的读取和处理速度更快,但将字符串迭代器转换回单个字符串并将其写入文件的最终步骤需要很长时间(几乎一秒钟)。我不会为整个文件群体做这件事情的数学计算,它们大约有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")更好的选择?有没有完全不同的方法可以提高我的文件处理速度。(记住,我有50K个文件,每个文件接近10K行。)

2个回答

4

你目前的操作是重复进行了2次:一次是遍历字符串并使用mkString "\n",另一次是将这些行写入文件。相反,你可以一步完成:

for(x <-processedLines){
    outFile.write(x);
    outFile.write("\n");
}

1
@Learner 我猜在 processedLines.mkString("\n") 中,你正在迭代处理过的行以附加 \n。然后下一次写入新生成的长字符串到文件时。 - Jatin
1
outFile 是什么类型?我的意思是它是 BufferedWriter 还是其他什么类型?如果它不缓冲,那么会消耗额外的时钟周期。 - Jatin
1
我不了解Resource类。但通常在这种情况下,瓶颈应该是I/O。如果是CPU,则存在问题。尝试使用BufferedWriter并进行比较。 - Jatin
1
@Learner 你可能想尝试使用outFile.writeStrings而不是outFile.writeStrings(processedLines,"\n")(http://jesseeichar.github.io/scala-io-doc/0.3.0/api/scalax/io/SeekableByteChannelResource.html)。但我仍然认为,BufferedWriter应该是最快的方法。 - Jatin
1
@学习者 请执行以下代码:for(x <-processedLines){ bufferedWriter.write(x); bufferedWriter.write("\n"); } - Jatin
显示剩余6条评论

1
您的写作速度较慢,因为您正在使用一个“迭代器”。 “Iterator”是延迟评估的。事实上,不是您的写作速度慢,而是“迭代器”的评估速度慢。 “Iterator”是延迟评估的。这意味着它在使用时被评估。因为您正在映射“Iterator”的元素,所以它产生一个新的未评估的“Iterator”。它将在您调用“mkString”时被评估。此函数将“Iterator”转换为存储在RAM中的“String”。为避免这种情况,我建议使用一个接受“迭代器”的写函数,正如Jatin所建议的那样。您可以重写他的代码,如下所示:
processedLines.foreach(line => {
  outfile.write(line)
  outfile.write("\n")
}

这实际上是对一个 Iterator 进行的操作。它会逐行评估并写入。


感谢@T.Grotker的解释。这个过程比之前的方法要好一些,但我不会说好多少。 - Learner
1
实际上,您只需遍历一次迭代器(或字符串),而不是两次,就可以获得性能的提升。 - tgr
我会说是的。更改读取方式是否会提高写入性能? - Learner
1
是的和不是。你只需要将计算从mkString转移到程序的另一个点。这是我目前能想到的最好的解决方案。 - tgr
你可以详细说明一下或者提供一些链接来解释你的意思吗?谢谢! - Learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接