Skip to content

Commit c6b626c

Browse files
committed
Extracted btset to
1 parent f346ff0 commit c6b626c

28 files changed

Lines changed: 151 additions & 3307 deletions

File tree

CHANGELOG.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
11
# WIP
22

3+
- Fixed DB and Datom pprinting (#287)
34
- Fixed cases when upsert resolves to tempid (#285)
4-
- Throw on tempid in `:db.fn/cas` (closes #264)
5+
- Throw on tempid in `:db.fn/cas` (#264)
6+
- `distinct` aggregate returns set not a vector (thx @jdf-id-au)
7+
- Ability to run tests with Kaocha
8+
- [ BREAKING ] Some internals of `datascript.arrays`, `datascript.btset` and `datascript.Datom` type has changed
9+
10+
Performance optimizations for JVM version:
11+
12+
- Reimplemented btset in Java with transients and better performance
13+
- Extracted btset to `[persistent-sorted-set "0.1.0"]`
14+
- Used raw ints in Datom intead of wrapped Integers, added stored in tx sign
15+
16+
Numbers I get on my 3.2 GHz i7-8700B (median time per test, ms):
17+
18+
| version | add-1 | add-5 | add-all | init | retract-5 | q1 | q2 | q3 | q4 | qpred1 | qpred2 |
19+
|------------------|---------|-------|---------|------|-----------|-----|------|------|------|--------|--------|
20+
| 0.17.1-jvm | 795.8 | 670.7 | 651.8 | 79.4 | 617.5 | 2.3 | 5.4 | 8.2 | 13.1 | 7.1 | 27.3 |
21+
| 0.18.0-jvm | 625.2 | 450.9 | 401.8 | 21.8 | 389.5 | 1.9 | 5.4 | 8.2 | 13.3 | 7.3 | 28.9 |
22+
| 0.9.5703-datomic | 1693.9 | 737.9 | 528.5 | --- | 1420.9 | 2.8 | 5.2 | 7.3 | 9.3 | 12.8 | 15.5 |
23+
| 0.18.0-v8 | 1231.6 | 963.1 | 930.3 | 76.5 | 809.1 | 6.4 | 15.2 | 23.8 | 33.6 | 24.2 | 24.5 |
24+
25+
Tests are as follows:
26+
27+
| Test | Description |
28+
|-----------|-------------|
29+
| add-1 | Add 100k datoms to an empty DB, one datom per transaction |
30+
| add-5 | Add 20k entities to an empty DB, 5 datoms per transaction, 100k datoms total |
31+
| add-all | Add 20k entities to an empty DB in a single transaction, 100k datoms total |
32+
| init | “Fast” datascript DB creation from an already sorted array of datoms (used in DB deserialization), 100k datoms |
33+
| retract-5 | Retract 20k entities from a DB with 100k datoms. Each entity removes 5 datoms. 1 entity per tx. |
34+
| q1 | Query with 1 clause over a DB with 100k datoms, ~12k tuples in resultset `[:find ?e :where [?e :name "Ivan"]]` |
35+
| q2 | Query with 2 clauses, 1 join, ~12k tuples `[:find ?e ?a :where [?e :name "Ivan"] [?e :age ?a]]` |
36+
| q3 | Query with 3 clauses, 2 joins, ~6k tuples `[:find ?e ?a :where [?e :name "Ivan"] [?e :age ?a] [?e :sex :male]]` |
37+
| q4 | Query with 4 clauses, 3 joins, ~6k tuples `[:find ?e ?l ?a :where [?e :name "Ivan"] [?e :last-name ?l] [?e :age ?a] [?e :sex :male]]` |
38+
| qpred1 | Query with a predicate, ~50k tuples `[:find ?e ?s :where [?e :salary ?s] [(> ?s 50000)]]` |
39+
| qpred2 | Query with a predicate and dynamic input, ~50k tuples `[:find ?e ?s :in $ ?min_s :where [?e :salary ?s] [(> ?s ?min_s)]]` |
40+
41+
For Datomic an `datomic:mem://` database was used.
42+
43+
What we see:
44+
45+
- 20..40% faster transactions,
46+
- 75% faster deserialization (db-init),
47+
- No significant change on queries,
48+
- JVM transactions are more than twice as fast as V8,
49+
- JVM queries are 3-4 times as fast as V8,
50+
- DataScript transactions are 25..70% faster that Datomic in-memory. Query times vary.
551

652
# 0.17.1
753

bench/bench.clj

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@
5555
(= "rebuild" arg)
5656
(recur (assoc opts :rebuild true) (next args))
5757

58-
(re-matches #"(jvm|v8|dtmc)" arg)
58+
(re-matches #"(jvm|v8|datomic)" arg)
5959
(recur (update opts :versions conj ["latest" arg]) (next args))
6060

6161
(re-matches #"(\d+\.\d+\.\d+|[0-9a-fA-F]{40}|latest)" arg)
6262
(recur (update opts :versions conj [arg "jvm"]) (next args))
6363

64-
(re-matches #"(\d+\.\d+\.\d+|[0-9a-fA-F]{40}|latest)-(jvm|v8|dtmc)" arg)
65-
(let [[_ version vm] (re-matches #"(\d+\.\d+\.\d+|[0-9a-fA-F]{40}|latest)-(jvm|v8|dtmc)" arg)]
64+
(re-matches #"(\d+\.\d+\.\d+|[0-9a-fA-F]{40}|latest)-(jvm|v8|datomic)" arg)
65+
(let [[_ version vm] (re-matches #"(\d+\.\d+\.\d+|[0-9a-fA-F]{40}|latest)-(jvm|v8|datomic)" arg)]
6666
(recur (update opts :versions conj [version vm]) (next args)))
6767

6868
:else
@@ -76,23 +76,26 @@
7676
(apply run "clojure" "-Sdeps"
7777
(cond
7878
(= "latest" version)
79-
"{:paths [\"src\" \"../src\" \"../target/classes\"]}"
79+
(str "{:paths [\"src\"]"
80+
" :deps {datascript {:local/root \"..\"}}}")
8081

8182
(re-matches #"\d+\.\d+\.\d+" version)
82-
(str "{:deps {datascript {:mvn/version \"" version "\"}}}")
83+
(str "{:paths [\"src\"]"
84+
" :deps {datascript {:mvn/version \"" version "\"}}}")
8385

8486
(re-matches #"[0-9a-fA-F]{40}" version)
85-
(str "{:paths [\"src\" \"../target/classes\"] :deps {datascript {:git/url \"https://github.com/tonsky/datascript.git\" :sha \"" version "\"}}}"))
87+
(str "{:paths [\"src\"]"
88+
" :deps {datascript {:git/url \"https://github.com/tonsky/datascript.git\" :sha \"" version "\"}}}"))
8689
"-m" "datascript-bench.datascript"
8790
benchmarks)
8891

8992
"v8"
9093
(apply run "node" "run_v8.js" benchmarks)
9194

92-
"dtmc"
95+
"datomic"
9396
(apply run "clojure" "-Sdeps"
9497
(str "{"
95-
" :paths [\"src\" \"src-dtmc\"]"
98+
" :paths [\"src\" \"src-datomic\"]"
9699
" :deps {com.datomic/datomic-free {:mvn/version \"" (if (= "latest" version) "0.9.5703" version) "\"}}"
97100
"}")
98101
"-m" "datascript-bench.datomic"
File renamed without changes.

bench/src/datascript_bench/datascript.cljc

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
(:require
33
[clojure.string :as str]
44
[datascript.core :as d]
5-
[datascript.btset :as btset]
65
[datascript-bench.core :as core]
76
[datascript.query-v3 :as q3]))
87

8+
99
#?(:cljs
1010
(enable-console-print!))
1111

12+
1213
(def schema
1314
{ :follows { :db/valueType :db.type/ref
1415
:db/cardinality :db.cardinality/many } })
1516

17+
1618
(defn- wide-db
1719
([depth width] (d/db-with (d/empty-db schema) (wide-db 1 depth width)))
1820
([id depth width]
@@ -26,6 +28,7 @@
2628
(mapcat #(wide-db % (dec depth) width) children)))
2729
[{:db/id id :name "Ivan"}])))
2830

31+
2932
(defn- long-db [depth width]
3033
(d/db-with (d/empty-db schema)
3134
(apply concat
@@ -156,30 +159,6 @@
156159
[?x :follows ?t]
157160
(follows ?t ?y)]]))))
158161

159-
; (defn ^:export bench-btset []
160-
; (doseq [[tn target] [["sorted-set" (sorted-set)]
161-
; ["vector" []]
162-
; ["btset" (btset/btset)]]
163-
; ;; distinct? [true false]
164-
; size [100 500 20000]
165-
; :let [range (if true ;; distinct?
166-
; (shuffle (range size))
167-
; (repeatedly size #(rand-int size)))
168-
; shuffled-range (shuffle range)
169-
; set (into target range)]]
170-
; (core/bench {:target tn :test "set-conj" :size size}
171-
; (into target range))
172-
; (when (re-find #"set" tn)
173-
; (core/bench {:target tn :test "set-disj" :size size}
174-
; (reduce disj set shuffled-range))
175-
; (core/bench {:target tn :test "set-lookup" :size size}
176-
; (doseq [i shuffled-range]
177-
; (contains? set i))))
178-
; (core/bench {:target tn :test "set-iterate" :size size}
179-
; (doseq [x set]
180-
; (+ 1 x)))
181-
; (core/bench {:target tn :test "set-reduce" :size size}
182-
; (reduce + 0 set))))
183162

184163
#?(:clj
185164
(defn ^:export -main [& names]

deps.edn

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
{ :aliases {
1+
{
2+
:deps {
3+
persistent-sorted-set {:mvn/version "0.1.0"}
4+
}
5+
6+
:aliases {
27
:1.9 {
38
:override-deps {
49
org.clojure/clojure {:mvn/version "1.9.0"}

dev.html

Lines changed: 0 additions & 23 deletions
This file was deleted.

dev/user.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848

4949
(defn retest-all []
5050
(clojure.tools.namespace.repl/refresh)
51-
(clojure.test/run-all-tests #"datascript\.test\.(?!btset).*"))
51+
(clojure.test/run-all-tests #"datascript\.test\."))
5252

5353
#_(retest-all)
5454

project.clj

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,31 @@
99
:dependencies [
1010
[org.clojure/clojure "1.10.0" :scope "provided"]
1111
[org.clojure/clojurescript "1.10.516" :scope "provided"]
12+
[persistent-sorted-set "0.1.0"]
1213
]
1314

1415
:plugins [
1516
[lein-cljsbuild "1.1.7"]
16-
; [lein-virgil "0.1.9"]
1717
]
1818

1919
:global-vars {
2020
*warn-on-reflection* true
2121
*print-namespace-maps* false
2222
;; *unchecked-math* :warn-on-boxed
2323
}
24-
:java-source-paths ["src-java"]
2524
:jvm-opts ["-Xmx2g" "-server"]
2625

27-
:aliases {"test-clj" ["run" "-m" "datascript.test/test-most"]
28-
"test-clj-all" ["run" "-m" "datascript.test/test-all"]
26+
:aliases {"test-clj" ["run" "-m" "datascript.test/test-clj"]
27+
"test-cljs" ["do" ["cljsbuild" "once" "release" "advanced"]
28+
["run" "-m" "datascript.test/test-node" "--all"]]
2929
"node-repl" ["run" "-m" "user/node-repl"]
3030
"browser-repl" ["run" "-m" "user/browser-repl"]
31-
"test-all" ["do" ["clean"]
32-
["test-clj-all"]
33-
["cljsbuild" "once" "release" "advanced"]
34-
["run" "-m" "datascript.test/test-node" "--all"]]}
31+
"test-all" ["do" ["clean"] ["test-clj"] ["test-cljs"]]}
3532

3633
:cljsbuild {
3734
:builds [
3835
{ :id "release"
39-
:source-paths ["src" "bench/src"]
36+
:source-paths ["src"]
4037
:assert false
4138
:compiler {
4239
:output-to "release-js/datascript.bare.js"
@@ -50,7 +47,7 @@
5047
:notify-command ["release-js/wrap_bare.sh"]}
5148

5249
{ :id "advanced"
53-
:source-paths ["src" "bench/src" "test"]
50+
:source-paths ["src" "test"]
5451
:compiler {
5552
:output-to "target/datascript.js"
5653
:optimizations :advanced
@@ -77,7 +74,7 @@
7774
}}
7875

7976
{ :id "none"
80-
:source-paths ["src" "bench/src" "test" "dev"]
77+
:source-paths ["src" "test"]
8178
:compiler {
8279
:main datascript.test
8380
:output-to "target/datascript.js"
@@ -93,7 +90,7 @@
9390
:profiles {
9491
:1.9 { :dependencies [[org.clojure/clojure "1.9.0" :scope "provided"]
9592
[org.clojure/clojurescript "1.9.946" :scope "provided"]] }
96-
:dev { :source-paths ["bench/src" "test" "dev"]
93+
:dev { :source-paths ["test" "dev"]
9794
:dependencies [[org.clojure/tools.nrepl "0.2.13"]
9895
[org.clojure/tools.namespace "0.2.11"]
9996
[lambdaisland/kaocha "0.0-389"]

src-java/datascript/ASortedSet.java

Lines changed: 0 additions & 83 deletions
This file was deleted.

src-java/datascript/ISortedSet.java

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)