Recently I watched a talk about DefRecord DefType in Clojure and ClojureScript given by Michał Marczyk at Clojure/West 2016.
Its a great talk on the details of implement of the two data types.
What I found interesting was that Michał emphasised that a lot of work has gone on to make deftype
really performant in Clojurescript.
So, I decided to check how deftype
performs in comparison to defrecord
and a normal map
.
To test the performance, I used the scaffolding I had worked on and described here.
I created Foo1
using deftype
and Foo2
using a defrecord
. Here is the code:
I tested the performance of following three things:
(.-x f1)
(:x f2)
(:x 1)
which are the idiomatic ways of data access for the three data types.
All results are for Chrome 52.0.2734.0 canary (64-bit) on Mac OS X:
Type | Mean Timing |
---|---|
deftype access | 1.2000012871293235e-8 |
defmethod access | 4.8206608599135286e-8 |
map access | 6.966344634811152e-8 |
So in this example, field access for a deftype
is 4 times faster than that for defmethod
and 7 times faster than a normal map
.
The speed of deftype
method access makes some sense because it generates a javascript class and we are doing a direct field access for it whereas for the two there are different levels of indirection.
Now onto function invocation for the two datatypes.
I tested the performance of following two things:
(add-num f1 1)
(add-num f2 1)
Type | Mean Timing |
---|---|
deftype function call | 1.3490893960300394e-8 |
defmethod function call | 1.519495239675906e-8 |
The results here are mixed.
I looked at the generated javascript code to understand what is happening:
expands to
whereas
expands to
So we need to look at the definition of add_num
.
The key thing is if the first argument to add_num
is non-null and it’s prototype has a method called bench$core$IAdd$add_num$arity$2
defined, then it is called with the two argument.
Looking at the code for Foo1
and Foo2
, we see that the method is defined.
The function call for the two datatypes looks exactly the same. This explains the similarity in performance of the two.
Hopefully this gives you an insight on reading javascript code generated by clojurescript.