user=> (def r (range 1))
user=> (for [a r, b r, c r, d r, e r, f r, g r, h r :when (and (= 0 a) (not= 1 b))]
(list a b c d e f g h))
((0 0 0 0 0 0 0 0))
user=> (doseq [a r, b r, c r, d r, e r, f r, g r, h r :when (and (= 0 a) (not= 1 b))]
(println (list a b c d e f g h)))
CompilerException java.lang.RuntimeException: Method code too large!, compiling:(/tmp/form-init8346140986526777871.clj:1:1)
Похоже, это исходит от clojure.asm.MethodWriter а>. Мой поиск в Google этой ошибки с Clojure почти не дает результатов.
Итак... что, черт возьми, происходит? Насколько глубока эта кроличья нора? Действительно ли эта одна строка кода Clojure создает метод > 65 КБ (значение взято из источника MethodWriter)?
Если этот ответ затрагивает проблему, с которой я сталкиваюсь, то (а) почему фрагментация означает, что вместо этого она растет экспоненциально линейно? И (б) каковы последствия для меня как программиста? Например, является ли это поведение общеизвестным и преднамеренным? Следует ли мне избегать использования doseq
в любой ситуации с более чем 3 или 4 привязками? Как это соотносится с использованием for
и doall
?
Возможно связано:
for
иdoseq
будетfor
, который создаст более крупный метод. Еслиdoseq
имеет такую неэффективность, то мне было бы интересно узнать, при каком пороге сложности вы получите лучшую производительность с(def ignore (doall (for [stuff] (side-effect)))
вместо более естественного(doseq [stuff] (side-effect))
. - person galdre   schedule 14.10.2014doseq
генерирует больше кода (ОП уже знал об этом) и что это связано с фрагментацией. Почему фрагментация означает, что он растет экспоненциально, а не линейно? Является ли это поведение хорошо известным и преднамеренным? Есть ли у него преимущество перед использованиемfor
иdoall
? - person galdre   schedule 14.10.2014