Мне действительно нравится with-out-str
подход к такого рода вещам:
(with-out-str
(println)
(doseq [s ["one" "two"]]
(println (.toUpperCase ^String s))))
Кажется, он примерно в 2-3 раза медленнее, чем ваш оригинальный подход и вариант "комбинированной карты и вставки" Мартина сдобавлены подсказки типа (и ~ в 30 раз быстрее, чем cl-format
, что, однако, явно выигрывает в коэффициенте крутизны :-)).(См. В конце этого ответа примечание о намеках и размышлениях.)
Еще одна версия, призванная поддерживать дух timtowtdi: для максимальной скорости (до ~ 2-кратного ускорения по сравнению с исходной версией), если ваместь причина позаботиться об этом, вы можете использовать
(loop [sb (doto (StringBuilder.)
(.append \newline))
strs ["one" "two"]]
(if-let [s (first strs)]
(do (.append sb (.toUpperCase ^String s))
(.append sb \newline)
(recur sb (next strs)))
(.toString sb)))))
Несколько касательно основного вопроса, я рассчитал все подходы после того, как избавился от всех предупреждений об отражении;в частности, я использовал
(def up #(.toUpperCase ^String %))
(кстати, #(.foo %)
, кажется, используется намного чаще, чем memfn
, даже когда подсказки типов не указаны.)