Использование Ruby для преобразования диапазона в массив и нехватка памяти
Сначала я делаю что-то простое
Рубиновый код:
(0...693530740).to_a
Это приводит к
NoMemoryError: failed to allocate memory
Ну, я в тупике. Есть ли способ изменить объем памяти, который может использовать интерпретатор ruby? Я не вижу как. У меня нет никакого способа обойти это, поскольку это должно существовать в моем коде. Есть ли способ лучше? Возможно, есть язык более низкого уровня, который может это сделать? Любые идеи приветствуются. Я уже пробовал использовать jRuby и дать jvm 15 ГБ памяти, но не повезло.
Спасибо за чтение этого вопроса
3 ответа
Зачем вам нужен массив из сотен миллионов элементов? Вам действительно нужно хранить все эти элементы в памяти одновременно или вы можете обрабатывать их один за другим, чтобы те, которые уже были обработаны, собирались? Что-то вроде этого:
(0...693530740).each do |n|
# do something
end
"У меня нет никакого способа обойти это, поскольку это должно существовать в моем коде"
Измените свой код так, чтобы он вам не понадобился. У вас есть только один кусок значимых данных здесь, число 693530740
, который отлично вписывается в 8 байтов. Маловероятно, что вам действительно нужно расширить его в этот огромный массив. Большинство методов массива Ruby, которые могут вам понадобиться, будут иметь эквиваленты (используя Range
, или же Enumerator
) которые работают без необходимости создания такого списка номеров.
Если у вас возникли проблемы с определением того, какого рода перепроектирование позволит избежать большого массива, то напишите новый вопрос - здесь, о переполнении стека, если дизайн можно изложить в кратком описании и нескольких строках кода. Возможно, codereview.stackexchange.com, если не представляется возможным продемонстрировать ваш алгоритм в виде небольшого фрагмента кода.
Итак, вы хотите выделить массив с ~650 миллионами чисел. что составляет ~2,6 ГБ. Обратите внимание, что эта память должна быть непрерывной. Не зная, сколько у вас физической памяти, я думаю, что это главная причина, по которой вы не можете это сделать