I'm doing some <canvas /> work and I was having some real trouble getting it performant.
The cause: I was looping over every pixel inside a `(go ...)`. This appears to sabotage `loop` and `doseq` perf, but only in ClojureScript. Numbers below.
These numbers are taken with:
[org.clojure/clojurescript "0.0-2511"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
though I also saw this issue with [org.clojure/clojurescript "0.0-2644"].
It gets dramatically worse as you increase the pixel count. With 4 million pixels the increase is 6ms => 2265ms, pure overhead. If you move the loop into a helper function, the issue goes away.
ClojureScript:
(time
(loop [i 0]
(when (< i 40000)
(recur (inc i)))))
; "Elapsed time: 1 msecs"
(go
(time
(loop [i 0]
(when (< i 40000)
(recur (inc i))))))
; "Elapsed time: 23 msecs"
(time
(doseq [i (range 40000)]))
; "Elapsed time: 32 msecs"
(go (time
(doseq [i (range 40000)])))
; "Elapsed time: 94 msecs"
Clojure:
(time
(loop [i 0]
(when (< i 40000)
(recur (inc i)))))
; "Elapsed time: 1.954785 msecs"
(go
(time
(loop [i 0]
(when (< i 40000)
(recur (inc i))))))
; "Elapsed time: 1.826223 msecs"
(time
(doseq [i (range 40000)]))
; "Elapsed time: 11.048818 msecs"
(go
(time
(doseq [i (range 40000)])))
; "Elapsed time: 11.668555 msecs"