Created
July 25, 2012 11:33
-
-
Save jonase/3175654 to your computer and use it in GitHub Desktop.
query performance predictability
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(use '[datomic.api :only [db q] :as d]) | |
(def schema | |
[{:db/id #db/id[:db.part/db] | |
:db/ident :num | |
:db/valueType :db.type/long | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db} | |
{:db/id #db/id[:db.part/db] | |
:db/ident :parent | |
:db/valueType :db.type/ref | |
:db/cardinality :db.cardinality/one | |
:db.install/_attribute :db.part/db}]) | |
(defn make-tree [root node-fn child-count-fn depth] | |
(if (zero? depth) | |
(node-fn) | |
[root | |
(map #(make-tree % node-fn child-count-fn (dec depth)) | |
(repeatedly (child-count-fn) node-fn))])) | |
(defn num-tree [root] | |
(make-tree root #(rand-int 9) #(inc (rand-int 5)) 5)) | |
(defmulti emit (fn [pid o] (type o))) | |
(defmethod emit Number [pid n] | |
(let [id (d/tempid :db.part/user)] | |
[[:db/add id :num n] | |
[:db/add id :parent pid]])) | |
(defmethod emit clojure.lang.IPersistentVector [pid [root children]] | |
(let [id (d/tempid :db.part/user)] | |
(concat [[:db/add id :num root]] | |
(when pid [[:db/add id :parent pid]]) | |
(mapcat #(emit id %) children)))) | |
(def num-db | |
(let [uri "datomic:mem://numtrees"] | |
(d/delete-database uri) | |
(d/create-database uri) | |
(let [conn (d/connect uri)] | |
(d/transact conn schema) | |
;; Add 20 trees with roots numbered from 100 to 119 | |
(doseq [n (range 100 120)] | |
(d/transact conn (emit nil (num-tree n)))) | |
(db conn)))) | |
(def descendant | |
'[[[descendant ?a ?b] ;; ?b is a descendant of ?a if | |
[?b :parent ?a]] ;; ?b:s parent is ?a | |
[[descendant ?a ?b] ;; or | |
[?x :parent ?a] ;; the parent of ?x is ?a | |
[descendant ?x ?b]]]) ;; and ?x is a descendant of ?a | |
(dotimes [_ 5] | |
(time | |
(q '[:find ?desc | |
:in $ % | |
:where | |
[?root :num 100] | |
[descendant ?root ?desc]] | |
num-db descendant))) | |
;; ~20 msecs | |
(dotimes [_ 5] | |
(time | |
(q '[:find ?desc | |
:in $ % | |
:where | |
[?root :num 100] | |
[descendant ?root ?desc] | |
[?desc :num 4]] | |
num-db descendant))) | |
;; ~3000 msecs | |
(dotimes [_ 5] | |
(time | |
(q '[:find ?desc | |
:in $ % | |
:where | |
[?root :num 100] | |
[descendant ?root ?desc] | |
[?desc :num ?n] | |
[(= ?n 4)]] | |
num-db descendant))) | |
;; back to ~20 msecs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment