Javaのループを使ってナイーブで非遅延型のmap
をJavaで実装したいと思います。 私の主な関心事は、Clojureのjavaでの関数呼び出しです。ここで Clojure関数をJavaに効率的に渡します。
package java_utils;
import java_utils.ApplyFn;
public class NaiveClojure {
public static Object[] map (ApplyFn applyfn, Object function, Object[] coll) {
int len = coll.length;
for (int i = 0 ; i < len ; i++) {
coll[i] = applyfn.apply(function, coll[i]);
}
return coll;
}
}
package java_utils;
public abstract class ApplyFn {
public abstract Object apply (Object function, Object value);
}
ApplyFn
という抽象クラスのJava を使用して機能を実現する(defn java-map [f coll]
(let [java-fn (proxy [ApplyFn] []
(apply [f x]
(f x)))]
(seq (NaiveClojure/map java-fn f (to-array coll)))))
私は私のポイントはmap
をアウトパフォームすることはない
(doall (map inc (range 0 10000))) ;; 3.4 seconds for 10000 operations
(java-map inc (range 0 10000) ;; 5.4 seconds
を試してみました(私は例として、それを実装)、私はちょうど(Clojureのの車輪の再発明をしないように)特定の機能とそのようなことをしたいです。
このような関数を渡すより良い方法はありますか? (簡単で速い方法として) 一般的に私のコーディングを改善する(私は理論的知識が不十分です)、ここでperfを殺していることは分かりますか? 私は、オブジェクトのような一般的なタイピングを言うだろうが、私はあなたがここに心配のための原因を持っていない何かが
おかげ
これはパフォーマンス測定を行う信頼性の高い方法ではありません(基準をチェックアウトしてください)、x2の減速はパフォーマンスが低下することはほとんどありません。あなたがClojure関数をラップしているという唯一の事実は、より多くの作業を行っているので、なぜそれが遅いのかを説明することができます。 –
ああ、ライブラリ名のおかげで、実際には私の機能は、時間と基準のベンチの両方でシーケンスのclojureマップよりも速いようです。私はIFnを使用するか、より良いアプローチがよりよい結果を生み出すかどうか疑問に思った。 –
高速であれば、配列をインプレースで更新している可能性が高い(** clojure.core/mapと同じセマンティクスではない!) –