Делаем ruby ​​быстрее для программ, интенсивно использующих память - PullRequest
2 голосов
/ 27 сентября 2011

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

Программа состоит из двух этапов: (1) создать большой hash: string => list впамять, (2) сделать некоторые вычисления на хэш.Замедление происходит в фазе 1.

Почему это происходит?Неужели звонков в сборщик мусора больше?Или ruby ​​подменяет память на диск?

В любом случае, могу ли я что-нибудь сделать, чтобы ускорить процесс?Например, могу ли я увеличить размер кучи или максимальный объем памяти, который разрешено использовать ruby?Я ничего не видел на странице руководства.

1 Ответ

1 голос
/ 27 сентября 2011

Я считаю, что ruby ​​тоже очень медленный с большими наборами данных, способ, которым я справляюсь с этим, это запуск ruby ​​1.9.2 или выше, или даже jruby, если это возможно.Если этого недостаточно, при обходе очень больших наборов данных я обычно возвращаюсь к парадигме mapreduce, поэтому мне нужно хранить только одну строку в памяти за раз.Если что-то похоже на вашу проблему с построением хеша, я бы просто использовал программу ruby, генерирующую $ stdout для цепочки или переадресации вывода в файл:

$ ruby build_csv.rb > items.csv
$ cat items.csv
foo,23
foo,17
bar,42

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

@hsh = Hash.new { |hash, key| hash[key] = [] }
File.open("items.csv").each_line do |l|
  k,v = l.split(',')
  @hsh[k] << v
end

Предыдущая программа, конечно, могла бы быть быстрее, если бы использовалась библиотека CSV.В любом случае, он будет читать в hsh что-то вроде этого.

@hsh => {"foo"=>[23, 17], "bar"=>[42]} 

Разделение проблемы на множество небольших программ действительно влияет на скорость, потому что меньше сохраняется в памяти, если операция над хешемнужно работать только с одним ключом, тогда легко записать эту часть как что-то, что просто читает, пока новый ключ не найден, производит вывод по последнему ключу и затем продолжает работу с новым ключом, почти так же, как первыйкруглый.Сокращение использования памяти таким образом путем разделения и получения промежуточных результатов в файле действительно значительно ускоряет процесс.Если вы можете разделить свои данные, вы также можете запускать несколько этапов одно / сопоставления одновременно или в оболочке, или с помощью потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...