我有一个 Clojure 程序,它返回even
下面的延迟斐波那契数序列的总和n
:
(defn sum-of-even-fibonaccis-below-1 [n]
(defn fib [a b] (lazy-seq (cons a (fib b (+ b a)))))
(reduce + (take-while (partial >= n) (take-nth 3 (fib 0 1)))))
(time (dotimes [n 1000] (sum-of-even-fibonaccis-below-1 4000000))) ;; => "Elapsed time: 98.764msecs"
这不是很有效。但是,如果我不减少序列并简单地返回一个值列表,(0 2 8 34 144...)
它可以将其工作速度提高 20 倍:
(defn sum-of-even-fibonaccis-below-2 [n]
(defn fib [a b] (lazy-seq (cons a (fib b (+ b a)))))
(take-while (partial >= n) (take-nth 3 (fib 0 1))))
(time (dotimes [n 1000] (sum-of-even-fibonaccis-below-2 4000000))) ;; => "Elapsed time: 5.145msecs"
为什么reduce
这个懒惰的 Fibonacci 序列成本如此之高,我怎样才能在不放弃惯用的 Clojure 的情况下加快它的速度?