Welcome! Please see the About page for a little more info on how this works.

+7 votes
ago in Metadata by

I found that with-meta applied to a function returns an instance of RestFn.
However, I know that invoking a function through applyTo is much slower than through invoke.
The benchmarks in :thread: confirm this.

Is it a problem that a function with metadata is slower than it could be?

If so, I could propose a solution - to proxy all methods like invoke to the original function, not just applyTo.

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFunction.java#L31-L33

(require '[criterium.core :as c])

(defn f [x]
  x)

(c/quick-bench
    (f 1))
;; Execution time mean : 1,642094 ns

(defn wrapper [f]
  (fn [y]
    (f y)))

(let [f' (wrapper f)]
  (c/quick-bench (f' 1)))
;; Execution time mean : 5,016630 ns

(let [f'' (with-meta f {:foo :bar})]
  (c/quick-bench (f'' 1)))
;; Execution time mean : 31,332965 ns

(defn wrapper' [f]
  (fn [& args]
    (apply f args)))

(let [f''' (wrapper' f)]
  (c/quick-bench (f''' 1)))
;; Execution time mean : 41,983970 ns

Additional links:
- https://clojurians.slack.com/archives/C03S1KBA2/p1740750168290999
- https://github.com/camsaul/methodical/pull/150

1 Answer

0 votes
ago by

Wouldn't it make more sense to focus on making applyTo faster?

...