Skip to content

Commit

Permalink
Optimize hot-path methods
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-yakushev committed Aug 2, 2024
1 parent 7d94fde commit 8a1391b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/methodical/impl/cache/simple.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[methodical.util.describe :as describe]
[pretty.core :as pretty])
(:import
(clojure.lang IPersistentMap IDeref)
(methodical.interface Cache)))

(set! *warn-on-reflection* true)
Expand All @@ -21,7 +22,8 @@

Cache
(cached-method [_ dispatch-value]
(get @atomm dispatch-value))
;; This code is very hot, hence direct interop makes a difference here.
(.valAt ^IPersistentMap (.deref ^IDeref atomm) dispatch-value))

(cache-method! [_ dispatch-value method]
(swap! atomm assoc dispatch-value method))
Expand Down
40 changes: 20 additions & 20 deletions src/methodical/impl/multifn/cached.clj
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,26 @@
(CachedMultiFnImpl. new-impl (i/empty-copy cache)))))

(effective-method [_ dispatch-value]
(or
(.cached-method cache dispatch-value)
;; just like vanilla multimethods, we will add a new entry for every unique dispatch value we encounter, so
;; there's an implicit assumption that dispatch values are bounded
;;
;; build the effective method for dispatch value. We may end up throwing this out, but we currently need to build
;; it to determine the effective dispatch value.
(let [method (i/effective-method impl dispatch-value)
effective-dispatch-value (:dispatch-value (meta method))
;; If a method with the same effective dispatch value is already cached, add the existing method to the
;; cache for dispatch value. This way we don't end up with a bunch of duplicate methods impls for various
;; dispatch values that have the same effective dispatch value
cached-effective-dv-method (.cached-method cache effective-dispatch-value)
method (or cached-effective-dv-method method)]
;; Make sure the method was cached for the effective dispatch value as well, that way if some less-specific
;; dispatch value comes along with the same effective dispatch value we can use the existing method
(when-not cached-effective-dv-method
(i/cache-method! cache effective-dispatch-value method))
(i/cache-method! cache dispatch-value method)
method)))
(if-some [cached (.cached-method cache dispatch-value)]
cached
;; just like vanilla multimethods, we will add a new entry for every unique dispatch value we encounter, so
;; there's an implicit assumption that dispatch values are bounded
;;
;; build the effective method for dispatch value. We may end up throwing this out, but we currently need to build
;; it to determine the effective dispatch value.
(let [method (i/effective-method impl dispatch-value)
effective-dispatch-value (:dispatch-value (meta method))
;; If a method with the same effective dispatch value is already cached, add the existing method to the
;; cache for dispatch value. This way we don't end up with a bunch of duplicate methods impls for various
;; dispatch values that have the same effective dispatch value
cached-effective-dv-method (.cached-method cache effective-dispatch-value)
method (or cached-effective-dv-method method)]
;; Make sure the method was cached for the effective dispatch value as well, that way if some less-specific
;; dispatch value comes along with the same effective dispatch value we can use the existing method
(when-not cached-effective-dv-method
(i/cache-method! cache effective-dispatch-value method))
(i/cache-method! cache dispatch-value method)
method)))

clojure.protocols/Datafiable
(datafy [this]
Expand Down

0 comments on commit 8a1391b

Please sign in to comment.