tonsky / datascript

Immutable database and Datalog query engine for Clojure, ClojureScript and JS
Eclipse Public License 1.0
5.45k stars 304 forks source link

Improve performance of getter-fn and tuple-key-fn #438

Closed bsless closed 1 year ago

bsless commented 1 year ago

getter-fn:

We can dispatch to a slightly more efficient getter based on the type of the index, and eliminate an instance check. If the index is a number, we can dispatch via nth or array, and cast to a primitive in advance.

If it is not a number, we know the target can't be an array.

tuple-key-fn:

We can completely eliminate mapping getter-fn over attributes

First, we can check the count of common attributes before mapping, thus short circuiting the non-composite key earlier.

Otherwise, we can build the key while iterating on arrays, significantly faster.

bsless commented 1 year ago

When I tested these improvements on https://github.com/bsless/tools.analyzer.datalog I got ~2.5x performance boost

bsless commented 1 year ago

The before/after benchmarks: java 8:

add-1                 249.2 ms/op   245.3 ms/op
add-5                 491.2 ms/op   466.0 ms/op
add-all               495.1 ms/op   468.2 ms/op
freeze                580.2 ms/op   581.6 ms/op
init                   18.2 ms/op    18.3 ms/op
pull-many               1.1 ms/op     1.1 ms/op
pull-many-entities      3.0 ms/op     2.9 ms/op
pull-one              0.579 ms/op   0.640 ms/op
pull-one-entities       1.0 ms/op   0.975 ms/op
pull-wildcard           1.4 ms/op     1.5 ms/op
q1                    0.954 ms/op   0.696 ms/op
q2                      2.1 ms/op     2.2 ms/op
q3                      3.2 ms/op     3.1 ms/op
q4                      4.5 ms/op     4.4 ms/op
qpred1                  4.5 ms/op     4.6 ms/op
qpred2                 10.3 ms/op    10.0 ms/op
retract-5             395.0 ms/op   388.0 ms/op
rules-long-10x3         1.6 ms/op     1.5 ms/op
rules-long-30x3        15.3 ms/op    14.1 ms/op
rules-long-30x5        20.9 ms/op    18.9 ms/op
rules-wide-3x3        0.451 ms/op   0.418 ms/op
rules-wide-4x6         11.3 ms/op    10.0 ms/op
rules-wide-5x3          3.8 ms/op     3.4 ms/op
rules-wide-7x3         56.0 ms/op    49.6 ms/op

Java 17:

add-1                 235.4 ms/op   247.9 ms/op
add-5                 453.5 ms/op   459.6 ms/op
add-all               458.0 ms/op   463.8 ms/op
freeze                571.7 ms/op   567.8 ms/op
init                   19.7 ms/op    21.1 ms/op
pull-many               1.2 ms/op     1.2 ms/op
pull-many-entities      2.8 ms/op     2.9 ms/op
pull-one              0.611 ms/op   0.614 ms/op
pull-one-entities     0.928 ms/op   0.943 ms/op
pull-wildcard           1.4 ms/op     1.4 ms/op
q1                    0.702 ms/op   0.718 ms/op
q2                      2.3 ms/op     2.2 ms/op
q3                      3.2 ms/op     3.1 ms/op
q4                      4.7 ms/op     4.6 ms/op
qpred1                  4.9 ms/op     4.6 ms/op
qpred2                 10.2 ms/op     9.4 ms/op
retract-5             378.2 ms/op   393.4 ms/op
rules-long-10x3         1.5 ms/op     1.4 ms/op
rules-long-30x3        14.4 ms/op    13.2 ms/op
rules-long-30x5        19.7 ms/op    17.8 ms/op
rules-wide-3x3        0.417 ms/op   0.398 ms/op
rules-wide-4x6         10.8 ms/op     9.5 ms/op
rules-wide-5x3          3.7 ms/op     3.2 ms/op
rules-wide-7x3         53.2 ms/op    46.4 ms/op
tonsky commented 1 year ago

Thank you!

tonsky commented 1 year ago

Published in 1.4.0