在Clojure中运行Java代码的速度与Java中的Java相同

ada*_*ham 0 clojure

我有以下代码:

(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))
Run Code Online (Sandbox Code Playgroud)

问题来自Java,这个代码的运行速度比编译代码后从Clojure调用它快大约100倍.有没有什么方法可以从Clojure获得相同的Java性能,或者它总是会变慢?

ama*_*loy 8

这里有更多的类型提示,而你所拥有的那些类型提示是这样的,我不完全确定它们有什么好处 - 你真的应该提示a中的名字let,而不是值.也就是说(let [^Observer obs (...)] ...),不是(let [obs ^Observer (...)] ...).在许多情况下,这两种方法都有效,但前者更"安全".这也是事实,你应该非常愿意选择reifyproxy这里,无论是性能,因为proxy当你能可能避免它被劝阻.

我不知道你正在使用的神经网络库,所以你可能需要在参数单typehint createStockMarketNeuralNetwork,但其余的是服务不到任何目的,以迷惑人谁读你的代码-它甚至有可能过度typehints会混淆编译器编写较慢的代码,如果你选择不准确的提示.因此,不要在整个代码中随意放置它们,切换到reifysw1nn建议的方法,然后设置*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))
Run Code Online (Sandbox Code Playgroud)