Java InteropのCloJure最適化
-
23-12-2019 - |
質問
既存のJavaクラスを操作するとき、私が誤って何かをした場合、反省の警告を受けます。
IllegalArgumentException一致するフィールドが見つかりません:クラスの取得 java.lang.String Clojure.lang.RefLector.GetInstanceField. (Reflector.java:271)
は、所与のメソッドの呼び出しごとに実行時に反射を行うクローブですか?またはこれはどんな方法でもキャッシュされていますか?関連するJavaクラスに関与しているあらゆる種類のJava-Interopを移動するためのスピード上の利点がありますか?
解決
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"
.
最初の関数は、呼び出されるたびに反射を使用します。2つ目は、ネイティブJavaコードと同様の性能を持っています。
他のヒント
反射警告ではない、それは反射を使用していたということだけです。
typeヒントを使用して反射を排除します。上記のリンク(デフォルトの偽)に記載されている*warn-on-reflection*
フラグは、オプションで反射警告を有効にします。
Leiningenのlein check
ユーティリティを使用するのが便利です。これは、プロジェクト内のすべてのClojureファイルをコンパイルしようとし、反射警告がオンになっています。これにより、コード内の反射問題、またはライブラリからロードされたコードで報告されます。
所属していません StackOverflow