我的最终解决方案
经过所有测试后,我发现两种略有不同的方法可以以足够的速度进行计算。
首先我使用了该功能diff
具有不同类型的返回值,下面是返回向量的代码,但我还计时了返回双数组的版本(用 y 替换 (vec y) )和 Incanter.matrix (用矩阵 y 替换 (vec y) ) 。该函数仅基于java数组。这是基于 Jouni 的代码,删除了一些额外的类型提示。
另一种方法是使用 Java 数组进行计算并将值存储在瞬态向量中。正如您从计时中看到的,如果您不希望函数返回并数组,则这比方法 1 稍快。这是在函数中实现的difft
.
因此,选择实际上取决于您不想对数据做什么。我想一个好的选择是重载该函数,以便它返回与调用中使用的相同类型。实际上将 java 数组传递给 diff 而不是向量会使速度加快约 1 秒。
不同功能的计时:
返回向量的差异:
(time (def y (diff x)))
"Elapsed time: 4733.259 msecs"
返回 Incanter.matrix 的 diff:
(time (def y (diff x)))
"Elapsed time: 2599.728 msecs"
diff 返回双数组:
(time (def y (diff x)))
"Elapsed time: 1638.548 msecs"
difft:
(time (def y (difft x)))
"Elapsed time: 3683.237 msecs"
功能
(use 'incanter.stats)
(def x (vec (sample-normal 1e7)))
(defn diff [x]
(let [y (double-array (dec (count x)))
x (double-array x)]
(dotimes [i (dec (count x))]
(aset y i
(- (aget x (inc i))
(aget x i))))
(vec y)))
(defn difft [x]
(let [y (vector (range n))
y (transient y)
x (double-array x)]
(dotimes [i (dec (count x))]
(assoc! y i
(- (aget x (inc i))
(aget x i))))
(persistent! y)))