2016-10-07 5 views
1

Javaのループを使ってナイーブで非遅延型のmapをJavaで実装したいと思います。 私の主な関心事は、Clojureのjavaでの関数呼び出しです。ここで Clojure関数をJavaに効率的に渡します。

は私のコードです:だからClojureの中で、私が持っているNaiveClojureというクラスが
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を殺していることは分かりますか? 私は、オブジェクトのような一般的なタイピングを言うだろうが、私はあなたがここに心配のための原因を持っていない何かが

おかげ

+0

これはパフォーマンス測定を行う信頼性の高い方法ではありません(基準をチェックアウトしてください)、x2の減速はパフォーマンスが低下することはほとんどありません。あなたがClojure関数をラップしているという唯一の事実は、より多くの作業を行っているので、なぜそれが遅いのかを説明することができます。 –

+0

ああ、ライブラリ名のおかげで、実際には私の機能は、時間と基準のベンチの両方でシーケンスのclojureマップよりも速いようです。私はIFnを使用するか、より良いアプローチがよりよい結果を生み出すかどうか疑問に思った。 –

+0

高速であれば、配列をインプレースで更新している可能性が高い(** clojure.core/mapと同じセマンティクスではない!) –

答えて

1

が表示されていない、あなたはそれをやっている方法は、罰金と効率的です。

coll[i] = applyfn.apply(function, coll[i]); 

これは非常に正常な方法です。 Valentin Waeselynck氏が指摘しているように、測定を行う際には、信頼できるマイクロベンチマーキング機能を使用することを忘れないようにしてください。また、この種の小さなコードチャンクのベンチマーキングは厄介です。

clojure関数を生成すると、applyというメソッドを持つ「通常の」Javaクラスが生成されます。もともとClojureで書かれた関数を呼び出しているので、通常のJava構文で記述されたクラスのメソッドを呼び出すよりも、呼び出すのが遅くなることはありません。ホットスポットJITは、それをウォームアップしてインライン化すると、メソッドコールがなくても速くなる可能性があります(これが、この種のベンチマークは直観的には困難です)。

+0

答えをいただきありがとうございます。このようなことをやっていたのは初めてのことでした。おそらく、特定のデータの速度を向上させるためのプリミティブのメソッドを記述しようとします –

関連する問題