如何提高Ruby代码的效率和速度

如何提高Ruby代码的效率和速度,ruby,performance,Ruby,Performance,我目前正在使用String.scan方法搜索某些单词或正则表达式的文件。但是,在1.9GB的数据上运行脚本时,大约需要3个小时。我认为这可能是由于重复使用.scan。 代码看起来很像下面,有没有办法提高速度,即使它意味着没有扫描 字符串“text”是本例中50k单词文件中的文本。 'item.getCustomeMetadata.putText'将结果放置在单独的程序中。 当一个数组用于pdCount,另一个用于idrCount时,代码会重复自身 idNames=[/UK[0-9]{3,6}/,

我目前正在使用String.scan方法搜索某些单词或正则表达式的文件。但是,在1.9GB的数据上运行脚本时,大约需要3个小时。我认为这可能是由于重复使用.scan。 代码看起来很像下面,有没有办法提高速度,即使它意味着没有扫描

字符串“text”是本例中50k单词文件中的文本。 'item.getCustomeMetadata.putText'将结果放置在单独的程序中。 当一个数组用于pdCount,另一个用于idrCount时,代码会重复自身 idNames=[/UK[0-9]{3,6}/,/\s*[A-C,E,G-H,J-PR-T,W-Z]{2}?:\s*\d\s*{6}[A-dfmA-DFM]?\s*/] idCats=[IG_EmpID,IG_SSN]

`

每个文件运行一次。所以你可以想象这将超过数百万。我曾想过使用线程,为每个文件创建一个线程,但这对我来说不起作用


谢谢你的帮助。

好的,有几点意见

最重要的是,每次调用scan时都要扫描整个文件,并且在循环中执行此操作。这是个坏主意。 你的正则表达式相当复杂,正则表达式本身也不快。 你的数据文件是结构化的吗?数据是否用制表符、管道或逗号分隔?数据通常出现在后续行的同一位置吗

能否将文件拆分为大小不超过1兆字节的较小工作集?这将大大加快在内存中搜索字符串的速度


老实说,如果我遇到这种情况,我会寻找delimeters或某种记录结构——如果数据是有规律的,那么可以根据这些数据进行假设和优化,然后在错误发生时进行处理。如果数据完全是自由格式的,那么唯一的选择就是将文件分割成更小的单元,并使用多个线程来处理它们。

Ruby是一种可爱的语言;但是为了快速处理文本,可以使用bash。看看grep和awk。不幸的是,它需要一个只接受Ruby的程序,否则我肯定会选择bash。谢谢,谢谢。不幸的是,我对你的建议无能为力。整个局势很难扭转。我运行脚本是为了与另一个程序协同工作,因此目前我正尝试使用更多的程序函数来加快运行速度。
idNames.each_with_index do |val, index|
    textScan = text.scan(val).size
    if textScan > idrHighest
        idrHighest = textScan
    end
    volume = volume + textScan
    item.getCustomMetadata.putText(idCats[index], textScan)
    if textScan != 0
        idrCount +=1
    end
end

pdRegNames = [/(\+44\s?7\d{3}|\(?07\d{3}\)?)\s?\d{3}\s?\d{3}/ , /020[0-9]{7}/ , /[a-zA-Z0-9_\.\-+]+@(infogov|gmail|hotmail|yahoo|outlook|aol|msn|verizon)(\.[a-z]{2,3}){1,2}/ , /(0[1-9]|[1-9]|[12][0-9]|3[01])[-\/ .](0[1-9]|[1-9]|1[012])[-\/ .](19|20)\d\d/ , /\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/, /[A-Z0-9]{5}\d[0156]\d([0][1-9]|[12]\d|3[01])\d[A-Z0-9]{3}[A-Z]{2}/,/([A-PR-UWYZ][A-HK-Y0-9][A-HJKS-UW0-9]?[A-HJKS-UW0-9]?)\s*([0-9][ABD-HJLN-UW-Z]{2})/i]
pdRegCats = ["IG_Phone","IG_Phone2","IG_Email","IG_DOB" , "IG_FIP", "IG_License", "IG_Address"]

pdRegNames.each_with_index do |val, index|
    textScan = text.scan(val).size
    if textScan > pdHighest
        pdHighest = textScan
    end
    volume = volume + textScan
    item.getCustomMetadata.putText(pdRegCats[index], textScan)
    if textScan != 0
        pdCount +=1
    end
end

maritalNames = ["Married" , "Divorced" , "Civil Partnership"]

temp = volume
maritalNames.each do |val|
    textScan = text.scan(/#{val}/i).size
    if textScan > pdHighest
        pdHighest = textScan
    end
    volume = volume + textScan
    item.getCustomMetadata.putText("IG_Marital", (volume - temp).round(0))
    if textScan != 0
        pdCount +=1
    end
end

foundSort = text.scan(/[0-9]{2}-[0-9]{2}-[0-9]{2}/)
textScan = 0
foundSort.each do |sort|
    if sortArray.include? sort
        textScan +=1
    end
end
if textScan > pdHighest
    pdHighest = textScan
end
volume = volume + textScan
item.getCustomMetadata.putText("IG_Sort", textScan)
if textScan != 0
    pdCount +=1
end