Как эффективно анализировать большие текстовые файлы в Ruby

Я пишу сценарий импорта, который обрабатывает файл, который потенциально имеет сотни тысяч строк (файл журнала). Использование очень простого подхода (см. Ниже) заняло достаточно времени и памяти, и я чувствовал, что он может вывести мой MBP в любой момент, поэтому я остановил процесс.

#...
File.open(file, 'r') do |f|
  f.each_line do |line|
    # do stuff here to line
  end
end

В этом файле, в частности, 642 868 строк:

$ wc -l nginx.log                                                                                                                                        /code/src/myimport
  642868 ../nginx.log

Кто-нибудь знает более эффективного (память / процессор) способа обработки каждой строки в этом файле?

UPDATE

Код внутри f. each_line сверху просто сопоставляет регулярное выражение со строкой. Если совпадение не удается, я добавляю строку в массив @skipped . Если он проходит, я форматирую совпадения в хэш (с ключом «поля» совпадения) и добавляю его в массив @results .

# regex built in `def initialize` (not on each line iteration)
@regex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) - (.{0})- \[([^\]]+?)\] "(GET|POST|PUT|DELETE) ([^\s]+?) (HTTP\/1\.1)" (\d+) (\d+) "-" "(.*)"/

#... loop lines
match = line.match(@regex)
if match.nil?
  @skipped << line
else
  @results << convert_to_hash(match)
end

Я полностью согласен с тем, что это неэффективный процесс. Я мог бы заставить код внутри convert_to_hash использовать предварительно вычисленную лямбду вместо того, чтобы каждый раз выяснять вычисления. Думаю, я просто предположил, что проблема была в самой итерации строки, а не в построчном коде.

6
задан localshred 31 January 2011 в 04:25
поделиться