Fork me on GitHub

Curious about an optimization that would detect when OK, and “lift” values. For example, this is a lot faster than the version in core:

(let [special-syms '#{if def fn* do let* loop* letfn* throw try catch finally recur new set! ns deftype* defrecord* . js* & quote case* var ns*}] 
 (defn special-symbol?
  (contains? special-syms x)))


Oh curious which way? Is a wrapping let faster than a def?


uh, the clojure compiler already does that "lifting" of constant values @mfikes


It is faster because it avoids constructing that set on each call.


Cool, if Clojure does that, perhaps ClojureScript could as well.


Oh ok yes it makes sense definitely. I actually always have a def for those things so I thought I was missing something


It might have effects on :advanced—perhaps it could be opt-in


@mfikes;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-41986 not sure if there ever was a ticket opened for this. if its done for CLJS however I would probably wrap it in a delay and inject a deref since we want to avoid constructing too many things on startup


can't sacrifice startup time in the browser


Right. Maybe even custom JavaScript based on checking for null to lazily construct. (To try to avoid any overhead associated with Delay objects.)


Hah. It's nearly trivial to take the stuff we did for ^:const and use it to detect constant maps, sets, vectors in the code and throw them into the constant table. Doing that, without changing any of the standard lib, causes special-symbol? to exhibit these speedups under script/simple-benchmark: V8: 1.26, SpiderMonkey 2.5, JavaScriptCore 3.2, Nashorn, 2.8, ChakraCore 3.5, GraalVM 1.9 Of course, that doesn't lazily construct them. But, on the other hand it theoretically aliases identical constants into the constant table. Here is my experimental branch: