Optional static vars in ArcadiaBehaviour
To support live coding, vars used in hooks are dereferenced on every invocation. This presents a 4x slowdown per-invocation.
;;; invoking identity 1 million times
(dotimes [__ 4]
(let [f identity]
(time (dotimes [_ 1e6] (f 100)))))
; "Elapsed time: 27 msecs"
; "Elapsed time: 25 msecs"
; "Elapsed time: 26 msecs"
; "Elapsed time: 23 msecs"
(dotimes [__ 4]
(let [f #'identity]
(time (dotimes [_ 1e6] (f 100)))))
; "Elapsed time: 92 msecs"
; "Elapsed time: 89 msecs"
; "Elapsed time: 88 msecs"
; "Elapsed time: 93 msecs"
Though, in practice, invocations are fast enough in general for this not to be an issue.
;;; invoking identity 1 thousand times
(dotimes [__ 4]
(let [f identity]
(time (dotimes [_ 1e3] (f 100)))))
; "Elapsed time: 0 msecs"
; "Elapsed time: 0 msecs"
; "Elapsed time: 0 msecs"
; "Elapsed time: 0 msecs"
(dotimes [__ 4]
(let [f #'identity]
(time (dotimes [_ 1e3] (f 100)))))
; "Elapsed time: 0 msecs"
; "Elapsed time: 0 msecs"
; "Elapsed time: 0 msecs"
; "Elapsed time: 0 msecs"
And run times become dominated by the actual running of the function for anything non-trivial
(dotimes [__ 4]
(let [f str]
(time (dotimes [_ 1e6] (f 100)))))
; "Elapsed time: 1347 msecs"
; "Elapsed time: 1303 msecs"
; "Elapsed time: 1352 msecs"
; "Elapsed time: 1319 msecs"
(dotimes [__ 4]
(let [f #'str]
(time (dotimes [_ 1e6] (f 100)))))
; "Elapsed time: 1358 msecs"
; "Elapsed time: 1338 msecs"
; "Elapsed time: 1399 msecs"
; "Elapsed time: 1368 msecs”
Still, an option to have the hooks' backing component ArcadiaBehaviour dereference their vars once on deserialization and use that value afterwards is reasonable. Exported games without changing vars would be the most immediate use case. This is somewhat similar to direct linking in Clojure 1.8.
I bet those benchmarks call invoke directly rather than via getRawRoot
A similar thing occurs with deftype protocols, where you modify the methods but the old instances behave as previously. The solution I use is to reconstruct the state explicitly, by a function call. Maybe a similar interface could be done with the static vars, where you opt the correct time to resolve?