繁体   English   中英

Ruby自定义拆分功能慢

[英]Ruby custom split function slow

我有一个很大的文件,大部分都是用空格分隔的数据,我想将其解析为哈希。 问题是这主要是用空格分隔的,因此一个简单的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,我无法控制它。

有可能使它更快吗?

您需要.squeeze.strip

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

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

压缩会将任何多余的空白压缩到仅1。条带将删除行的开头和结尾空间。

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

您还应该尽早提高期望,而无需遍历整个文件。

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

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"] 

要真正调整代码,您可以使用基准测试模块来查找瓶颈。

但我希望您代码的最大问题是字符串添加:

rowsplit[i] += byte

红宝石解释器将其翻译为

rowsplit[i] = rowsplit[i] + byte

这将为输入文件中的每个字节创建一个新的字符串对象。 因此,一个7MB的文件会创建并销毁700万个字符串对象...使用字符串串联方法可能会足够快:

rowsplit[i] << byte

请注意<<更改原始对象,这在您的程序中不是问题,但是在其他上下文中使用它时可能会出现问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM