stop using ConcurrentHashMap for inline cache, instead intern a new var at macro-time. 17% performance improvement for [:a :b :c] benchmark
This commit is contained in:
parent
a583540f21
commit
fbca7ab99c
2 changed files with 7 additions and 24 deletions
|
|
@ -724,23 +724,12 @@
|
||||||
params-maker ; can be null
|
params-maker ; can be null
|
||||||
])
|
])
|
||||||
|
|
||||||
#+clj
|
|
||||||
(defonce PATH-CACHE (java.util.concurrent.ConcurrentHashMap.))
|
|
||||||
|
|
||||||
(def MUST-CACHE-PATHS (mutable-cell false))
|
(def MUST-CACHE-PATHS (mutable-cell false))
|
||||||
|
|
||||||
(defn must-cache-paths!
|
(defn must-cache-paths!
|
||||||
([] (must-cache-paths! true))
|
([] (must-cache-paths! true))
|
||||||
([v] (set-cell! MUST-CACHE-PATHS v)))
|
([v] (set-cell! MUST-CACHE-PATHS v)))
|
||||||
|
|
||||||
#+clj
|
|
||||||
(defn add-path-cache! [k v]
|
|
||||||
(.put ^java.util.concurrent.ConcurrentHashMap PATH-CACHE k v))
|
|
||||||
|
|
||||||
#+clj
|
|
||||||
(defn get-path-cache [^String k]
|
|
||||||
(.get ^java.util.concurrent.ConcurrentHashMap PATH-CACHE k))
|
|
||||||
|
|
||||||
(defn- extract-original-code [p]
|
(defn- extract-original-code [p]
|
||||||
(cond
|
(cond
|
||||||
(instance? LocalSym p) (:sym p)
|
(instance? LocalSym p) (:sym p)
|
||||||
|
|
|
||||||
|
|
@ -435,29 +435,21 @@
|
||||||
prepared-path (ic-prepare-path local-syms expanded)
|
prepared-path (ic-prepare-path local-syms expanded)
|
||||||
possible-params (vec (ic-possible-params expanded))
|
possible-params (vec (ic-possible-params expanded))
|
||||||
|
|
||||||
;; TODO: unclear if using long here versus string makes
|
|
||||||
;; a significant difference
|
|
||||||
;; - but using random longs creates possibility of collisions
|
|
||||||
;; (birthday problem)
|
|
||||||
;; - ideally could have a real inline cache that wouldn't
|
|
||||||
;; have to do any hashing/equality checking at all
|
|
||||||
;; - with invokedynamic here, could go directly to the code
|
;; - with invokedynamic here, could go directly to the code
|
||||||
;; to invoke and/or parameterize the precompiled path without
|
;; to invoke and/or parameterize the precompiled path without
|
||||||
;; a bunch of checks beforehand
|
;; a bunch of checks beforehand
|
||||||
cache-id (if (= platform :clj) (i/gen-uuid-str))
|
cache-sym (vary-meta
|
||||||
cache-sym (if (= platform :cljs)
|
(gensym "pathcache")
|
||||||
(vary-meta
|
assoc :cljs.analyzer/no-resolve true)
|
||||||
(gensym "pathcache")
|
|
||||||
assoc :cljs.analyzer/no-resolve true))
|
|
||||||
|
|
||||||
info-sym (gensym "info")
|
info-sym (gensym "info")
|
||||||
|
|
||||||
get-cache-code (if (= platform :clj)
|
get-cache-code (if (= platform :clj)
|
||||||
`(i/get-path-cache ~cache-id)
|
`(i/get-cell ~cache-sym)
|
||||||
cache-sym
|
cache-sym
|
||||||
)
|
)
|
||||||
add-cache-code (if (= platform :clj)
|
add-cache-code (if (= platform :clj)
|
||||||
`(i/add-path-cache! ~cache-id ~info-sym)
|
`(i/set-cell! ~cache-sym ~info-sym)
|
||||||
`(def ~cache-sym ~info-sym))
|
`(def ~cache-sym ~info-sym))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -473,6 +465,8 @@
|
||||||
~(mapv (fn [p] `(fn [] ~p)) possible-params)
|
~(mapv (fn [p] `(fn [] ~p)) possible-params)
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
|
(if (= platform :clj)
|
||||||
|
(intern *ns* cache-sym (i/mutable-cell)))
|
||||||
`(let [info# ~get-cache-code
|
`(let [info# ~get-cache-code
|
||||||
|
|
||||||
^com.rpl.specter.impl.CachedPathInfo info#
|
^com.rpl.specter.impl.CachedPathInfo info#
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue