2012-03-31 30 views
0
Clojure中運行Java代碼相同的速度與Java

我有以下代碼:從Java

(let [obs ^java.util.Observer (proxy [java.util.Observer] [] 
       (update [^Object o ^String arg] 
       (println arg))) 
     network ^StockPriceNeuralNetwork (NeuralNetworkFactory/createStockMarketNeuralNetwork ^java.util.List [^java.util.Observer obs])] 
    (.trainForTime ^StockPriceNeuralNetwork network)) 

的問題是從Java的代碼運行約100倍的速度比它從Clojure的調用它一旦代碼已編譯。有什麼辦法可以從Clojure中獲得相同的Java性能,或者它會一直比較慢嗎?

回答

8

這裏有更多的輸入提示,而你確實有這些輸入提示,以至於我不完全確定他們的確做得很好 - 你真的應該在let中提示這個名字,而不是值。也就是,(let [^Observer obs (...)] ...),而不是(let [obs ^Observer (...)] ...)。在許多情況下,這兩種方法都可行,但前者更「安全」。同樣,在這裏你應該更喜歡reify而不是proxy,這兩者都是爲了表現,因爲proxy在你可以避免的時候是不鼓勵的。

我不知道你在用神經網絡庫,這樣你就可以需要在參數createStockMarketNeuralNetwork單typehint,但其餘的是服務,除了混淆的人誰讀你的代碼沒有任何意義 - 這是如果您選擇的提示不準確,甚至有可能過度的提示會將編譯器混淆爲編寫較慢的代碼。因此,不要在整個代碼中隨意放置它們,而應切換到swlnn建議的reify方法,然後將*warn-on-reflection*設置爲true,並查看反射是否有問題。下面是一個reify一個版本的代碼,並移除所有我知道typehints後沒有什麼區別:

(let [obs (reify java.util.Observer 
      (update [this o arg] 
       (println arg))) 
     ^StockPriceNeuralNetwork network (NeuralNetworkFactory/createStockMarketNeuralNetwork ^java.util.List [obs])] 
    (.trainForTime network)) 
+0

我刪除我的回答,就像你說的類型提示被混淆... – sw1nn 2012-04-02 17:19:59