Ich habe ein Clojure-Programm, das die Summe einer faulen Folge von even
Fibonacci-Zahlen unter n
zurück:Warum verlangsamt das Reduzieren dieser Lazy-Sequenz dieses Clojure-Programm 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"
Es ist nicht sehr effizient. Aber wenn ich nicht die Sequenz reduzieren und einfach eine Liste von den Werten (0 2 8 34 144...)
kann es seine Aufgabe 20x schneller tun:
(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"
Warum ist reduce
so teuer zu dieser faulen Fibonacci-Folge, und wie kann ich beschleunigen es auf, ohne idiomatische Clojure zu verlassen?
Ich bin verwirrt von Ihrer Antwort. Die "-1" -Methode war anfangs langsam. Wie hast du es geschafft, in 8,5 ms auf deinem Rechner zu arbeiten? Einfach eine schnellere Maschine? – alt
Wahrscheinlich. Hast du versucht, den zweiten Test mit 'dorun' zu machen? Welche Ergebnisse hast du bekommen? –
ETA: Hinzufügen von Dorun legt es wieder auf 90 ms – alt