From fbca7ab99c84d93a28f7773f1c56be12e1a939a3 Mon Sep 17 00:00:00 2001 From: Nathan Marz Date: Tue, 31 May 2016 23:04:24 -0400 Subject: [PATCH] stop using ConcurrentHashMap for inline cache, instead intern a new var at macro-time. 17% performance improvement for [:a :b :c] benchmark --- src/clj/com/rpl/specter/impl.cljx | 11 ----------- src/clj/com/rpl/specter/macros.clj | 20 +++++++------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/clj/com/rpl/specter/impl.cljx b/src/clj/com/rpl/specter/impl.cljx index d443009..1012908 100644 --- a/src/clj/com/rpl/specter/impl.cljx +++ b/src/clj/com/rpl/specter/impl.cljx @@ -724,23 +724,12 @@ params-maker ; can be null ]) -#+clj -(defonce PATH-CACHE (java.util.concurrent.ConcurrentHashMap.)) - (def MUST-CACHE-PATHS (mutable-cell false)) (defn must-cache-paths! ([] (must-cache-paths! true)) ([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] (cond (instance? LocalSym p) (:sym p) diff --git a/src/clj/com/rpl/specter/macros.clj b/src/clj/com/rpl/specter/macros.clj index 9b7a077..15301de 100644 --- a/src/clj/com/rpl/specter/macros.clj +++ b/src/clj/com/rpl/specter/macros.clj @@ -435,29 +435,21 @@ prepared-path (ic-prepare-path local-syms 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 ;; to invoke and/or parameterize the precompiled path without ;; a bunch of checks beforehand - cache-id (if (= platform :clj) (i/gen-uuid-str)) - cache-sym (if (= platform :cljs) - (vary-meta - (gensym "pathcache") - assoc :cljs.analyzer/no-resolve true)) + cache-sym (vary-meta + (gensym "pathcache") + assoc :cljs.analyzer/no-resolve true) info-sym (gensym "info") get-cache-code (if (= platform :clj) - `(i/get-path-cache ~cache-id) + `(i/get-cell ~cache-sym) cache-sym ) 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)) @@ -473,6 +465,8 @@ ~(mapv (fn [p] `(fn [] ~p)) possible-params) )) ] + (if (= platform :clj) + (intern *ns* cache-sym (i/mutable-cell))) `(let [info# ~get-cache-code ^com.rpl.specter.impl.CachedPathInfo info#