【发布时间】:2015-01-21 13:16:57
【问题描述】:
我正在尝试将一个大型文本文件(大约 200 万行数字,260MB)导入一个数组,对数组进行编辑,然后将结果写入一个新的文本文件,方法是:
file_data = File.readlines("massive_file.txt")
file_data = file_data.map!(&:strip)
file_data.each do |s|
s.gsub!(/,.*\z/, "")
end
File.open("smaller_file.txt", 'w') do |f|
f.write(file_data.map(&:strip).uniq.join("\n"))
end
但是,我收到了错误failed to allocate memory (NoMemoryError)。如何分配更多内存来完成任务?或者,理想情况下,我可以使用另一种方法来避免重新分配内存吗?
【问题讨论】:
-
如果我是你,我会专注于让这个更加渐进 - 没有必要一口气读完整个文件。
-
正如@FrederickCheung 建议的那样,您应该一次读取一行输入文件。你可以用IO#foreach:
IO.foreach("input_file") do |line| ... end来做到这一点。在块中转换line,然后将其附加到输出文件中。 -
您应该明白,您正在内存中制作数据的多个副本。在您的 f.write 行上,“map”、“uniq”和“join”都将制作数据的完整副本,“uniq”可能会将其删减。尽管如此,当您将其相乘时,260MB 开始累加起来。在这里听取其他人的建议并简单地逐步处理数据。
-
另一种方法,根据您的需要,可能是使用数据库。 SQLite 应该能够轻松处理这么多数据,而无需担心内存使用。
标签: ruby arrays memory-management