java互操作的Clojure优化
在使用现有java类时,如果我做了一些错误的事情,我经常会收到反射警告,例如: IllegalArgumentException未找到匹配字段:类的获取 java.lang.String clojure.lang.Reflector.getInstanceField (Reflector.java:271)java互操作的Clojure优化,clojure,clojure-java-interop,Clojure,Clojure Java Interop,在使用现有java类时,如果我做了一些错误的事情,我经常会收到反射警告,例如: IllegalArgumentException未找到匹配字段:类的获取 java.lang.String clojure.lang.Reflector.getInstanceField (Reflector.java:271) clojure是否在运行时为给定方法的每次调用进行反射?或者这是以任何方式缓存的?将任何涉及的java互操作移动到相关的java类中会有速度方面的好处吗?这不是反射警告,只是指示它正在使用反
clojure是否在运行时为给定方法的每次调用进行反射?或者这是以任何方式缓存的?将任何涉及的java互操作移动到相关的java类中会有速度方面的好处吗?这不是反射警告,只是指示它正在使用反射 可以使用来消除反射。上述链接中所述的
*反射时发出警告*
标志(默认为false)可选择启用反射警告
我发现使用Leiningen的
lein check
实用程序很方便,它尝试编译项目中的每个Clojure文件,并打开反射警告。这将报告代码中或从库中加载的任何代码中的反射问题。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代码类似。谢谢,这非常有用。