-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add lightweight keyset wrapper #527
base: master
Are you sure you want to change the base?
Conversation
Saves on allocation and provides an immutable facade to underlying regular set
98bc16b
to
bed82e1
Compare
I believe the difference is significant enough to consider this given the benefit for larger schemas: (cc/quick-bench
;; 1.799482 µs -> 1.694608 µs
(m/-parse-entries [[:x int?] [:y {:optional true} boolean?] [:z string?]] nil nil))
(cc/quick-bench
;; 5.412949 µs -> 4.899880 µs
(m/-parse-entries [[:a int?]
[:b {:optional true} boolean?]
[:c string?]
[:u int?]
[:v int?]
[:w int?]
[:x int?]
[:y int?]
[:z int?]]
nil nil)) |
@ikitommi any interest in this patch? I can rebase it. |
Thanks for your work on this. Could you check the #539 , in which, I swapped the set to be a map with key->index mapping. This allows effective patching with reusing the parse-results. |
... the map generation could be improved I think, just collect the key-index pairs, create a arraymap in the end? |
The same mechanism I used for the set could be used here - use a mutable java collection and expose it later by an immutable "view" |
maybe just collecting the key + values into object-array and create persistent with |
Creating an ArrayMap is tricky. You don't want to do it for over 8 keys, and createWithCheck will be worst-case quadratic for it. |
we already do object-arrays for everything else, just one with double size? looks fast and does fast duplicate key check: (let [m {:a 1, :b 2, :c 3, :d 4, :e 5}
a (object-array (* 2 (count m)))]
(doseq [[i [k v]] (map-indexed vector m)]
(aset a (* i 2) k)
(aset a (inc (* i 2)) v))
(assert (= m (clojure.lang.PersistentArrayMap/createWithCheck a)))
;; 27ns
(cc/quick-bench
(clojure.lang.PersistentArrayMap/createWithCheck a))) |
static public PersistentArrayMap createWithCheck(Object[] init){
for(int i=0;i< init.length;i += 2)
{
for(int j=i+2;j<init.length;j += 2)
{
if(equalKey(init[i],init[j]))
throw new IllegalArgumentException("Duplicate key: " + init[i]);
}
}
return new PersistentArrayMap(init);
} It's not slow, but need to be aware it's quadratic, don't know what which size it becomes too heavy |
Saves on allocation and provides an immutable facade to underlying
regular set
Followup to #522
Part of #513