Как быстро обрезать и копировать большие файлы данных?


5

Я бы хотел быстро и эффективно отрезать большие файлы данных, вплоть до концерта. Если я использую что-то вроде «CUT» UNIX, это очень быстро, даже в среде CYGWIN.

Я пробовал разрабатывать и сравнивать различные скрипты Ruby для обработки этих файлов и всегда заканчивать ледниковыми результатами.

Что бы вы сделали в Ruby, чтобы сделать это не так медленно?

1

Почему бы не объединить их вместе - с помощью разреза, чтобы делать то, что он делает лучше всего, и рубин, чтобы обеспечить клей/ценность добавить с результатами CUT? вы можете запускать скрипты, помещая их в обратных кавычках, как это:

puts `cut somefile > foo.fil` 
# process each line of the output from cut 
f = File.new("foo.fil") 
f.each{|line| 
} 
+1

вместо того, чтобы писать на временный файл, вы можете сделать: труба = IO.popen («вырезать ...»); pipe.each_line {| line | ...} 29 июл. 092009-07-29 16:22:34


2

Этот вопрос напоминает мне Тима Брея Wide Finder project. Самый быстрый способ, которым он мог читать логи Apache с помощью Ruby, и выяснить, какие статьи были извлечены больше всего, с помощью этого сценария:

counts = {} 
counts.default = 0 

ARGF.each_line do |line| 
    if line =~ %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) } 
    counts[$1] += 1 
    end 
end 

keys_by_count = counts.keys.sort { |a, b| counts[b] <=> counts[a] } 
keys_by_count[0 .. 9].each do |key| 
    puts "#{counts[key]}: #{key}" 
end 

Потребовалось этот код 7½ секунд CPU, 13½ секунд истекшего к процессу миллион и записи изменений, четверть-триггер или около того, на прошлогодней PowerBook от 1,67 ГГц.


1

Я предполагаю, что ваши реализации Ruby считывают весь файл перед обработкой. Сокращение Unix работает, читая вещи по одному байту за раз и немедленно демпинг в выходной файл. Существует, конечно, некоторая буферизация, но не более нескольких килобайт.

Мое предложение: попробуйте сделать обработку на месте с минимальным пейджинговым или обратным трассированием, насколько это возможно.


0

Я сомневаюсь, что проблема в том, что ruby ​​считывает весь файл в памяти. Посмотрите на использование памяти и диска во время выполнения команды для проверки.

Я бы предположил, что основная причина заключается в том, что разрез написан на C и делает только одно, поэтому он, вероятно, скомпилирован до самого металла. Вероятно, это не так много, как вызов системных вызовов.

Однако рубиновая версия делает много вещей одновременно. Вызов метода намного медленнее в рубине, чем вызовы функции C.

Помните старость и trechery бить молодость и мастерство в UNIX: http://ridiculousfish.com/blog/archives/2006/05/30/old-age-and-treachery/