Clojure java interop optimization

When working with existing Java classes, I often get reflection warnings if I did something wrong, for example.

IllegalArgumentException No matching field found: gets for class java.lang.String clojure.lang.Reflector.getInstanceField (Reflector.java:271)

Is clojure a run-time reflection for every call to the specified methods? or is it cached in any way? Would there be a speed advantage to move any involved java-interop into the corresponding Java class?

+4
source share
2 answers

Clojure , , , . , , . :

user=> (set! *warn-on-reflection* true)

user=> (defn str-len [x] (.length x))
Reflection warning, NO_SOURCE_PATH:1:19 - reference to field length can't be resolved.

user=> (defn str-len-2 [^String x] (.length x))

user=> (str-len "abc") ; -> 3
user=> (str-len-2 "abc") ; -> 3

user=> (time (dotimes [_ 100000] (str-len "abc")))
"Elapsed time: 1581.163611 msecs"
user=> (time (dotimes [_ 100000] (str-len-2 "abc")))
"Elapsed time: 36.838201 msecs"

; Java.

+5

, , .

. *warn-on-reflection*, ( false), .

Leiningen lein check, Clojure . , .

+4

Source: https://habr.com/ru/post/1529270/


All Articles