【发布时间】:2011-10-24 11:05:36
【问题描述】:
我编写了一个简短的 Scala 程序来读取一个大文件,对其进行处理并将结果存储在另一个文件中。该文件包含大约 60000 行数字,我只需要从第三行中提取第一个数字。最终,我将这些数字保存到另一个文件中。虽然是数字,但我一直把它们当作字符串。
这是 Scala 代码:
import scala.io.Source
import java.io.BufferedWriter
import java.io.FileWriter
object Analyze {
def main(args: Array[String]) {
val fname = "input.txt"
val counters = Source.fromFile(fname).mkString.split("\\n").grouped(3)
.map(_(2).split("\\s+")(0))
val f = new BufferedWriter(new FileWriter("output1.txt"))
f.write(counters.reduceLeft(_ + "\n" + _))
f.close()
}
}
我非常喜欢 Scala 强大的 one liner 的能力。上述代码中的 one-liner 从文件中读取整个文本,将其拆分为行,将行分组为 3 行一组,然后从每组中取出第三行,将其拆分并取第一个数字。
这是等效的python脚本:
fname = 'input.txt'
with file(fname) as f:
lines = f.read().splitlines()
linegroups = [lines[i:i+3] for i in range(0, len(lines), 3)]
nums = [linegroup[2].split()[0] for linegroup in linegroups]
with file('output2.txt', 'w') as f:
f.write('\n'.join(nums))
Python 不具备这样的一种衬里。在上面的脚本中,第一行代码将文件读入行列表,下一行将行分成 3 组,下一行创建一个列表,其中包含每组最后一行的第一个数字。它与 Scala 代码非常相似,只是运行速度要快得多。
python 脚本在我的笔记本电脑上运行只需几分之一秒,而 Scala 程序运行 15 秒!我注释掉了将结果保存到文件的代码,持续时间下降到 5 秒,这仍然太慢了。我也不明白为什么将数字保存到文件需要这么长时间。当我处理较大的文件时,python 脚本运行了几秒钟,而 Scala 程序的运行时间是几分钟,我不能用它来分析我的文件。
感谢您对此问题的建议。 谢谢
【问题讨论】:
-
我还没有尝试过,但我觉得
mkString.split("\\n")不可能有效率。试试Source.fromPath("myfile.txt").getLines()或类似的东西。 -
您将此代码作为脚本运行(使用
scala命令)还是预编译?我认为你有这个问题,因为 scala 不是短跑运动员,它是长跑运动员(在启动时花费了大量时间 - 启动 JVM,检查类路径等等)。 -
嗨,我尝试用 getLines 替换 mkString.split("\\n") ,它确实显着提高了速度 - 收集数据只需一秒钟。仍然保存大约需要 5 秒。我发现
reduceLeft在大量数据上占用了剩下的时间,所以我将其转换为简单的for (c <- counters) f.write(c + "\n"),再次,时间显着缩短。整个过程现在大约需要 5 秒。但这仍然比 python 慢。
标签: scala