在Ruby中将csv数据读取到Time类的最快方法

时间:2014-02-16 02:08:52

标签: ruby performance csv

我一直在尝试将时间序列的Forex csv数据(超过100MB)解析为Ruby程序。 但我面临着处理速度问题的困难。

csv数据如下所示。 它按顺序包含“日期”,“时间”,“打开”,“关闭”,“高”,“低”,“音量”。

2007.01.02,07:00,119.01,119.01,119.01,119.01,8
2007.01.02,07:01,119.01,119.01,119.01,119.01,8
2007.01.02,07:02,119.01,119.01,119.01,119.01,8
2007.01.02,07:03,119.01,119.02,119.01,119.02,8
2007.01.02,07:04,119.02,119.03,119.01,119.02,8

我写了一个脚本来导入它。 我避免使用CSV库,因为解析CSV文件太慢了。 (与CSV.parse CSV.foreach一样)

IO.foreach(csv) do |line|
  res = line.split(",")
  Time.parse("%s %s"%[res[0], res[1]])
  res[2].to_f
  res[3].to_f
  res[4].to_f
  res[5].to_f
  res[6].to_i
end

当我执行这个程序时,Time.parse太慢了。 csv文件有250万行,所以它经历了250万次。

比较结果如下。

  • 使用Time.parse:160秒。
  • 使用Time.local:56秒。 (修改过的csv数据)
  • 使用Time.at:23秒。 (修改过的csv数据)
  • 没有Time Parse:只有10秒。

当我评论出Time.parse时,它变得更快。 我知道Time.now和Time.new没有争论很快。

有人有个好主意吗? 如果它使程序更快,我会毫不犹豫地为Ruby创建C库。

谢谢。

环境

  • Windows 7 x64
  • ruby​​ 2.0.0p247(2013-06-27)[i386-mingw32]

我将我的项目上传到Github。 https://github.com/pgkireek/ruby_trade

1 个答案:

答案 0 :(得分:1)

以下是您可以使用正则表达式的内容。匹配所有组并在Time.new中使用它们。

IO.foreach(csv) do |line|
    res = line.scan /((\d+)\.(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|\d+)/
    puts Time.new res[0][1], res[0][2], res[0][3], res[1][4], res[1][5]

    puts res[2][0].to_f
    puts res[3][0].to_f
    puts res[4][0].to_f
    puts res[5][0].to_f
    puts res[6][0].to_i
end

不确定,但使用正则表达式而不是拆分可能会快得多。