Arcadia icon indicating copy to clipboard operation
Arcadia copied to clipboard

Optional static vars in ArcadiaBehaviour

Open nasser opened this issue 8 years ago • 2 comments

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.

nasser avatar Mar 16 '17 01:03 nasser

I bet those benchmarks call invoke directly rather than via getRawRoot

timsgardner avatar Sep 16 '17 02:09 timsgardner

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?

pjago avatar Apr 04 '18 00:04 pjago