В дозе по сравнению с простой ленивой последовательностью заканчивается место в куче.

При стресс-тестировании некоторого кода Clojure на работе я заметил, что ему не хватает места в куче при переборе больших наборов данных. В конце концов мне удалось отследить проблемы до комбинации функции Clojure doseq и реализации ленивых последовательностей.

Это минимальный фрагмент кода, который приводит к сбою Clojure из-за исчерпания доступного места в куче:

(doseq [e (take 1000000000 (iterate inc 1))] (identity e))

В документации для doseq четко указано, что он не сохраняет заголовок ленивой последовательности, поэтому я ожидаю, что сложность памяти в приведенном выше коде будет близка к O (1). Есть что-то, что мне не хватает? Что за Clojure-идиоматический способ перебора чрезвычайно больших ленивых последовательностей, если doseq не подходит?


person the80srobot    schedule 13.08.2012    source источник
comment
Какую версию clojure и среду выполнения Java вы используете? Запуск этого кода в чистой реплике с clojure 1.4/java 1.6.0_33 на OSX показывает полностью статическое использование памяти чуть менее 400 МБ.   -  person Joost Diepenmaat    schedule 13.08.2012
comment
Вы уверены, что именно этот фрагмент вызывает проблему? На моем компьютере работает нормально (Clojure 1.4, JDK7, Windows, Eclipse/CCW). Было бы проблемой, если бы вы каким-то образом держались за начало последовательности, например. если (итерация вкл. 1) была сохранена где-то еще.   -  person mikera    schedule 14.08.2012
comment
Вы оба правы, проблема исчезает, когда я отключаю вещи, которые Leiningen 2 добавляет в REPL (история, навигация по клавишам и т. д.), и просто использую ванильный Clojure 1.4. Спасибо.   -  person the80srobot    schedule 14.08.2012


Ответы (1)


Когда я запускаю этот пример, я вижу, что использование памяти достигло 2,0 гигабайт, поэтому, возможно, у вас просто заканчивается оперативная память.

это действительно требует времени для запуска:

user=> (time (doseq [e (take 1000000000 (iterate inc 1))] (identity e)))
"Elapsed time: 266396.221132 msecs"

верх формы:

23999 arthur    20   0 4001m 1.2g 5932 S  213 15.3  17:11.35 java                                          
24017 arthur    20   0 3721m 740m 5548 S   88  9.3  13:49.95 java  
person Arthur Ulfeldt    schedule 13.08.2012