代码
def read_csv(fileName)
lines = (`wc -l #{fileName}`).to_i + 1
lines_processed = 0
open(fileName) do |csv|
csv.each_line do |line|
#process
lines_processed += 1
end
end
end
纯Ruby - 慢
def read_csv(fileName)
lines = open("sample.csv").count
lines_processed = 0
open(fileName) do |csv|
csv.each_line do |line|
#process
lines_processed += 1
end
end
end
基准
我跑了一个新的基准进行比较提供原始的方法和我自己。我还包括测试文件信息。
"File Information"
Lines: 1172319
Size: 126M
"django's original method"
Time: 18.58 secs
Memory: 0.45 MB
"OneNeptune's method"
Time: 0.58 secs
Memory: 2.18 MB
"Pure Ruby method"
Time: 0.96
Memory: 2.06 MB
说明
注:我添加了一个纯Ruby方法,因为使用wc
是有点欺骗,不便于携带。在大多数情况下,使用纯语言解决方案非常重要。
您可以使用此方法处理非常大的CSV文件。
〜2MB内存考虑到文件大小,我觉得它是非常优化的,这会增加内存使用量,但节省的时间似乎是公平交易,并且可以防止超时。
我没有修改方法来取一个文件名,但这只是因为我测试了很多不同的CSV文件,以确保它们都正常工作。如果你愿意,你可以删除它,但它可能会有帮助。
我也删除了偏移量的概念,因为您声明最初包含它以尝试优化自己的解析,但这不再必要。
此外,我还会跟踪文件中有多少行,以及您需要使用该信息后处理了多少行。请注意,这些行仅适用于基于unix的系统,这是避免将整个文件加载到内存中的技巧,它计算新行,并且我将1加到最后一行。如果您不打算将标题计为行,则可以删除+1并将行更改为“行”以更准确。
您可能遇到的另一个后勤问题是需要计算如果CSV文件具有标题时如何处理。
正如我的上传功能为我的应用程序 – django
您是否考虑在后台作业中处理CVS? – spickermann
不,因为我必须显示上传到用户的最终数量,如果有任何与csv有关的问题,我也必须告诉用户 – django