Fork me on GitHub
#clojurescript
<
2022-01-30
>
borkdude16:01:07

Using integers as map keys seems to be faster than keywords in CLJS. Maybe I'm doing it wrong. Is there a logical explanation for this? Perhaps it differs per JS platform. I tested this with planck.

(defn hash-test []
  (prn :hash-test)
  (let [m (into {} (zipmap (map keyword (map #(str "k" %) (range 20))) (range 20)))]
    (prn :m m)
    (time (dotimes [i 10000000] (-assoc m :k20 3) (.get m :k20 #_(keyword "20"))))))

(defn int-test []
  (prn :int-test)
  (let [m (into {} (zipmap (map identity (range 20)) (range 20)))]
    (prn :m m)
    (time (dotimes [i 10000000] (-assoc m 20 3) (.get m 20)))))

cljs.user=> (hash-test)
:hash-test
:m {:k19 19, :k8 8, :k11 11, :k18 18, :k5 5, :k12 12, :k7 7, :k13 13, :k9 9, :k15 15, :k6 6, :k16 16, :k17 17, :k0 0, :k10 10, :k3 3, :k4 4, :k14 14, :k1 1, :k2 2}
"Elapsed time: 7187.291315 msecs"
nil
cljs.user=> (int-test)
:int-test
:m {0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9, 10 10, 11 11, 12 12, 13 13, 14 14, 15 15, 16 16, 17 17, 18 18, 19 19}
"Elapsed time: 3892.295592 msecs"
nil

1
thheller16:01:58

in the REPL keywords are allocated each time they are used, so (-assoc m :k20 3) constructs the keyword every time. that may affect things

thheller16:01:02

only optimized builds optimize the constants allocation

p-himik16:01:24

In at least my dev setup with Chrome, the picture is the exact opposite - using keywords is almost twice as fast as numbers.

borkdude16:01:10

@thheller good point, the compiled code looks like new cljs.core.Keyword(null,\"k20\",\"k20\",(179847404)),(3)) - in advanced there would be some constant here?

thheller16:01:54

dunno how much that actually costs overall, but its a difference 😉

borkdude20:01:43

Are there any modern JS environments that do not support js/Reflect?

p-himik20:01:51

At lest for browsers, this website is generally considered a reliable source: https://caniuse.com/mdn-javascript_builtins_reflect

borkdude20:01:38

Yeah, I saw that. Just double checking. It seems relatively safe to assume that it exists...

p-himik20:01:37

Yeah, I would assume as much. NodeJS supports it, GraalVM JS does as well.

borkdude20:01:45

And Internet Explorer 11 isn't going to be supported after June 15th...