Skip to content
Andre R edited this page Dec 13, 2016 · 2 revisions

Hacking datascript code base

Some thoughts and possible optimization I wanted to write down:

Tuning compare functions

In datascript.db the compare functions will be heavily invoked by the btset. Assuming we only use keywords as attributes we can optimize them:

(defn- cmp-attr
  "@return {number}"
  [a1 a2]
  (if (or (nil? a1) (nil? a2))
    0
    #?(:cljs (js* "~{} > ~{} ? 1 : ~{} < ~{} ? -1 : 0"
                  (.-fqn a1) (.-fqn a2) (.-fqn a1) (.-fqn a2))
       :clj  (compare a1 a2))))

(defn- cmp-attr-quick
  "@return {number}"
  [a1 a2]
  ;; either both are keywords or both are strings
  #?(:cljs (js* "~{} > ~{} ? 1 : ~{} < ~{} ? -1 : 0"
                (.-fqn a1) (.-fqn a2) (.-fqn a1) (.-fqn a2))
     :clj  (.compareTo ^Comparable a1 a2)))

;; Etc.. (also for the other cmp-... functions

Advantages

  • Speed

Disadvantages

  • Doesn't work for javascript API.
  • The sort order among attributes doesn't agree with the clojurescript order. So the order of (d/datoms :eavt 8) will be different than before.

Lightweight datascript

Removing query engine

By removing the query engine you can still get a lot of the benefit (such as entities) and query for simple attr->value datoms.

Advantages

In a real world app, now datascript weighs in at only ~15kb gzipped. Ungzipped code is now only ~36kb.