我正在使用这种方法来处理一个大约有 220,000 行的文本文件。处理一个需要几分钟,但我有很多。有什么建议可以加快这个过程吗?
def parse_list(file_path,import=false)
# Parse the fixed-length fields
if File.exist?(file_path)
result=[]
File.readlines(file_path)[5..-1].each do |rs|
if rs.length > 140
r=rs.strip
unless r==''
filing={
'name' => r[0..50].strip,
'form' => r[51..70].strip,
'type' => r[71..80].strip,
'date' => r[81..90].strip,
'location' => r[91..-1].strip
}
result.push(filing)
end
end
end
return result
else
return false
end
end
更新:
最初,我认为使用 Nex 和 thetinman 的方法可以节省大量时间,所以我继续测试它们,以保持解析方法的一致性。
使用我原来r[].strip
的解析方法,但使用 Nex 的each_line
block 方法和 thetinman 的foreach
方法:
Rehearsal ---------------------------------------------
Nex 8.260000 0.130000 8.390000 ( 8.394067)
Thetinman 9.740000 0.120000 9.860000 ( 9.862880)
----------------------------------- total: 18.250000sec
user system total real
Nex 14.270000 0.140000 14.410000 ( 14.397286)
Thetinman 19.030000 0.080000 19.110000 ( 19.118621)
使用thetinman的unpack.map
解析方法再次运行:
Rehearsal ---------------------------------------------
Nex 9.580000 0.120000 9.700000 ( 9.694327)
Thetinman 11.470000 0.090000 11.560000 ( 11.567294)
----------------------------------- total: 21.260000sec
user system total real
Nex 15.480000 0.120000 15.600000 ( 15.599319)
Thetinman 18.150000 0.070000 18.220000 ( 18.217744)
unpack.map(&:strip)
vs r[].strip
: unpack
withmap
似乎并没有提高速度,但是将来会使用它是一种有趣的方法。
我发现了一个不同的问题:由于节省了大量时间,我想,我继续使用 pry 手动运行 Nex 和 thetinman 的方法。这是我发现我的电脑挂起的地方,就像我的原始代码一样。所以我继续测试,但使用的是我的原始代码。
Rehearsal ---------------------------------------------
Original 7.980000 0.140000 8.120000 ( 8.118340)
Nex 9.460000 0.080000 9.540000 ( 9.546889)
Thetinman 10.980000 0.070000 11.050000 ( 11.042459)
----------------------------------- total: 28.710000sec
user system total real
Original 16.280000 0.140000 16.420000 ( 16.414070)
Nex 15.370000 0.080000 15.450000 ( 15.454174)
Thetinman 20.100000 0.090000 20.190000 ( 20.195533)
我的代码、Nex 和 thetinman 的方法似乎具有可比性,其中 Nex 是使用 Benchmark 最快的。然而,Benchmark 似乎并没有说明全部情况,因为使用 pry 手动测试代码会使所有方法花费的时间大大延长,以至于我在取回结果之前取消了。
我还有一些问题:
- 在 IRB/Pry 中运行这样的东西是否有特定的东西会产生这些奇怪的结果,使代码运行速度大大降低?
- 如果我运行
original_method.count
、nex_method.count
或thetinmans_method.count
,它们似乎都很快返回。 - 由于内存问题和可扩展性,thetinman 和 nex 建议不要使用原始方法。但是,将来有没有办法用基准测试之类的方法来测试内存使用情况?
NEX 更新,使用activerecord-import
:
@nex,这是你的意思吗?这对我来说似乎仍然很慢,但我不确定你说的是什么意思:
在该块内导入一组数据。
你建议如何修改它?
def parse_line(line)
filing={
'name' => line[0..50].strip,
'form' => line[51..70].strip,
'type' => line[71..80].strip,
'date' => line[81..90].strip,
'location' => line[91..-1].strip
}
end
def import_files
result=[]
parse_list_nix(file_path){|line|
filing=parse_line(line)
result.push(Filing.new(filing))
}
Filing.import result #result is an array of new records that are all imported at once
end
activerecord-import
如您所见,该方法的结果要慢得多:
Rehearsal ------------------------------------------
import 534.840000 1.860000 536.700000 (553.507644)
------------------------------- total: 536.700000sec
user system total real
import 263.220000 1.320000 264.540000 (282.751891)
这种缓慢的导入过程是否正常?
它对我来说似乎超级慢。我试图弄清楚如何加快速度,但我没有想法。