У меня есть программа Clojure, которая возвращает сумму ленивой последовательности чисел Фибоначчей even
ниже n
:Почему уменьшение этой ленивой последовательности замедляет эту программу Clojure 20x?
(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...)
он может выполнять свою работу 20x быстрее:
(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
так дорого этой ленивой последовательности Фибоначчи, и как я могу ускорить это без отказа от идиоматического Clojure?
Я смущен вашим ответом. Метод '-1' начинался медленно. Как вы его смогли выполнить в 8.5 мсек на вашей машине? Просто быстрая машина? – alt
Возможно. Вы пытались запустить второй тест с помощью 'dorun'? Какие результаты вы получили? –
ETA: добавление dorun возвращает его обратно в 90 мкс – alt