Skip to content

Commit

Permalink
generator: Speed up use of functions as generators
Browse files Browse the repository at this point in the history
We previously reflected on a class every time to figure out how to
invoke it. Now we memoize that in a new Fn wrapper, and transparently
promote fns to that wrapper object whenever used in a generator context.
  • Loading branch information
aphyr committed Oct 17, 2022
1 parent 91d5e8f commit 165cba9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
30 changes: 25 additions & 5 deletions jepsen/src/jepsen/generator.clj
Expand Up @@ -496,6 +496,28 @@
(nil? (:type op)) (assoc! :type :invoke)))
:pending))

(defrecord Fn
[; We memoize the function's arity so we don't have to reflect
^long arity
; The function itself
f]
Generator
(update [this test ctx event] this)

; When asked for an op, we invoke f to produce a generator, then exhaust that
; before coming back to ourselves.
(op [this test ctx]
(when-let [gen (if (= arity 2)
(f test ctx)
(f))]
(op [gen this] test ctx))))

(defn fn-wrapper
"Wraps a function into a wrapper which makes it more efficient to invoke. We
memoize the function's arity, in particular, to reduce reflection."
[f]
(Fn. (first (util/arities (class f))) f))

(extend-protocol Generator
nil
(update [gen test ctx event] nil)
Expand All @@ -508,13 +530,11 @@
[op (if (= :pending op) this nil)]))

clojure.lang.AFunction
(update [f test ctx event] f)
(update [f test ctx event]
(update (fn-wrapper f) test ctx event))

(op [f test ctx]
(when-let [x (if (= 2 (first (util/arities (class f))))
(f test ctx)
(f))]
(op [x f] test ctx)))
(op (fn-wrapper f) test ctx))

clojure.lang.Delay
(update [d test ctx event] d)
Expand Down
5 changes: 3 additions & 2 deletions jepsen/src/jepsen/generator/context.clj
Expand Up @@ -21,7 +21,8 @@
IMap
Map
Set)
(java.util BitSet)))
(java.util BitSet)
(jepsen.generator.translation_table TranslationTable)))

;; Just for debugging
(extend-protocol Datafiable
Expand Down Expand Up @@ -98,7 +99,7 @@
^int next-thread-index
; A translation table for thread names. May include threads not in this
; context.
translation-table
^TranslationTable translation-table
; A bitset of thread indices which are active in this context
^BitSet all-threads
; A bitset of thread indices which are not busy evaluating anything
Expand Down

0 comments on commit 165cba9

Please sign in to comment.