Skip to content

Instantly share code, notes, and snippets.

@martintrojer
Created July 16, 2012 11:16
Show Gist options
  • Save martintrojer/3122185 to your computer and use it in GitHub Desktop.
Save martintrojer/3122185 to your computer and use it in GitHub Desktop.
core.logic datomic query blog
(defn bench [n f]
(let [rand-str #(str (java.util.UUID/randomUUID))
emails (repeatedly n rand-str)
name-email (reduce (fn [res em]
(conj res (vector (rand-str) (rand-str) em)))
[] emails)
email-height (reduce (fn [res em]
(conj res (vector em (rand-int 100))))
[] emails)]
(time (count (f name-email email-height)))))
(bench 5000 (partial q '[:find ?first ?height
:in [[?last ?first ?email]] [[?email ?height]]]))
;; "Elapsed time: 14757.248824 msecs"
;; 5000
(bench 5000 join-test)
;; "Elapsed time: 185.604 msecs"
;; 5000
;; Optimised Datomic query
(bench 5000 (partial q '[:find ?first ?height
:in $a $b
:where [$a ?last ?first ?email] [$b ?email ?height]]))
;; "Elapsed time: 10.869 msecs"
;; 5000
(binding-map '(?first ?last) ["John" "Doe"])
;; {?last "Doe", ?first "John"}
(q '[:find ?first ?height
:in [[?last ?first ?email]] [[?email ?height]]]
[["Doe" "John" "[email protected]"]
["Doe" "Jane" "[email protected]"]]
[["[email protected]" 73]
["[email protected]" 71]])
;; #<HashSet [["Jane" 73], ["John" 71]]>
(defn join-test [xs ys]
(let [rx (query '(?last ?first ?email) xs)
ry (query '(?email ?height) ys)
r (clojure.set/join rx ry)]
(map (juxt '?first '?height) r)))
(defn query [rule xs]
(let [prule (prep rule)]
(map #(binding-map* prule (prep %)) xs)))
(query '(?answer) (repeatedly 5 #(vector 42)))
;; ({?answer 42} {?answer 42} {?answer 42} {?answer 42} {?answer 42})
(join-test
[["Doe" "John" "[email protected]"]
["Doe" "Jane" "[email protected]"]]
[["[email protected]" 73]
["[email protected]" 71]])
;; (["John" 71] ["Jane" 73])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment