我有以下代码:
(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,这段代码运行的速度比编译代码时从Clojure调用代码快大约100倍。有没有什么方法可以从Clojure中获取相同的Java性能,或者它总是会变慢?
答案 0 :(得分:8)
这里有更多的类型提示,而你所拥有的那些类型提示使得我不能完全确定它们有什么好处 - 你真的应该在let
中暗示这个名字,不是价值。也就是说,(let [^Observer obs (...)] ...)
,而不是(let [obs ^Observer (...)] ...)
。在许多情况下,这两种方法都有效,但前者更“安全”。同样,你应该强烈要求reify
超过proxy
这里的性能,因为当你可以避免使用proxy
时,我们不鼓励这样做。
我不知道你正在使用什么神经网络库,所以你可能需要一个关于createStockMarketNeuralNetwork
的参数的单一类型提示,但其余的没有任何意义,除了混淆任何读取代码的人 - 如果选择不准确的提示,那么过多的类型提示甚至可能会使编译器混淆写入较慢的代码。因此,不要在整个代码中随意放置它们,而是切换到reify
方法sw1nn建议,然后将*warn-on-reflection*
设置为true,并查看反射是什么(如果有的话)。以下是此代码的reify
版本,在删除了我知道的所有类型提示后没有区别:
(let [obs (reify java.util.Observer
(update [this o arg]
(println arg)))
^StockPriceNeuralNetwork network (NeuralNetworkFactory/createStockMarketNeuralNetwork ^java.util.List [obs])]
(.trainForTime network))