首页 > 解决方案 > Ruby自定义拆分功能慢

问题描述

我有一个大部分以空格分隔的数据的大文件,我想将其解析为哈希。问题是这主要是用空格分隔的,所以简单string.split是行不通的。

以下是文件中某一行的简化示例:

field0 field1 [ [field2a] [field2b] ] field3

外括号(包括外括号)包含的内容需要是哈希成员。

我编写了以下函数,该函数有效,但速度很慢:

# row = String to be split
# fields = Integer indicating expected number of fields
def mysplit (row, fields)

 # Variable to keep track of brackets
 b = 0

 # Variable to keep track of iterations for array index
 i = 0

 rowsplit = Array.new(fields)
 rowsplit[0] = ""
 row.each_char do |byte|

  case byte

   when ' '
    if b == 0
     i += 1
     rowsplit[i] = ""
    else
     rowsplit[i] += byte
    end

   when '['
    b += 1
    rowsplit[i] += byte

   when ']'
    b -= 1
    rowsplit[i] += byte

   else
    rowsplit[i] += byte

  end

 end

 if i != fields - 1
  raise StandardError,
   "Resulting fields do not match expected fields: #{rowsplit}",
   caller
 elsif b != 0
  raise StandardError, "Bracket never closed.", caller
 else
  return rowsplit
 end

end

在 7 MB 6600 行长的文件上运行它需要 36 秒。值得一提的是,我的环境运行的是 Ruby 1.8.7,我无法控制它。

有没有可能让它更快?

标签: rubystringperformancesplitruby-1.8.7

解决方案


你想要.squeeze并且.strip

str = "  field0     field1 [ [field2a] [field2b] ] field3"

puts str.squeeze.strip
#=> "field0 field1 [ [field2a] [field2b] ] field3"

Squeeze 将任何额外的空白压缩为 1。Strip 将删除行的前导和尾随空间。

从那里您应该能够使用正则表达式模式匹配将每一行解析为您尝试创建的数据结构,但如果不知道如何解析数据,我将无能为力。

您还应该尝试尽快提高期望,无需遍历整个文件。

如果您知道您的行将在您的示例中匹配此模式:

if str.squeeze!.strip! !str[/\w+\ +\[\ +\[+\w+\]\ \[+\w+\]\ \]\ \w+/]
  raise StandardError, "Raise this string pattern is wrong #{str}"
end

如果你很好,那么你可以分裂或其他:

str.split(' ')
#=>["field0", "field1", "[", "[field2a]", "[field2b]", "]", "field3"] 

推荐阅读