在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中的代码运行速度大约是编译代码后从Clojure调用它的速度的100倍。有没有什么方法可以让我从Clojure调用它获得相同的Java性能,或者它总是更慢?

这里有比必要的多得多的类型提示,而且您所拥有的类型提示的位置使我不能完全确定它们是否有任何好处——您实际上应该在let中提示名称,而不是值。也就是说,(let [^Observer obs (...)] ...),而不是(let [obs ^Observer (...)] ...)。在许多情况下,这两种方法都有效,但前者"更安全"。同样,在这里,您应该更喜欢reify而不是proxy,这既是为了性能,也是因为proxy在您可能避免的情况下是不受欢迎的。

我不知道你使用的是什么神经网络库,所以你可能需要在createStockMarketNeuralNetwork的参数上使用一个类型提示,但其余的都没有用,只是为了迷惑任何阅读你代码的人——如果你选择了不准确的提示,甚至可能过多的类型提示会让编译器编写速度较慢的代码。因此,与其在整个代码中随机放置它们,不如切换到sw1nn建议的reify方法,然后将*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))

最新更新