Я только начал изучать Clojure. Одна из первых вещей, которые я заметил, это отсутствие циклов. Хорошо, я могу повториться. Поэтому давайте посмотрим на эту функцию (из Практического Clojure):
(defn add-up
"Adds up numbers from 1 to n"
([n] (add-up n 0 0))
([n i sum]
(if (< n i)
sum
(recur n (+ 1 i) (+ i sum)))))
Для достижения той же функции в Javascript мы используем такой цикл:
function addup (n) {
var sum = 0;
for(var i = n; i > 0; i--) {
sum += i;
}
return sum;
}
При выборе времени результаты выглядят так:
input size: 10,000,000
clojure: 818 ms
nodejs: 160 ms
input size: 55,000,000
clojure: 4051 ms
nodejs: 754 ms
input size: 100,000,000
clojure: 7390 ms
nodejs: 1351 ms
Затем я попытался попробовать классический фиб (после прочтения this):
в clojure:
(defn fib
"Fib"
[n]
(if (<= n 1) 1
(+ (fib (- n 1)) (fib (- n 2)))))
в js:
function fib (n) {
if (n <= 1) return 1;
return fib(n-1) + fib(n-2);
}
Опять же, производительность имеет определенную разницу.
fib of 39
clojure: 9092 ms
nodejs: 3484 ms
fib of 40
clojure: 14728 ms
nodejs: 5615 ms
fib of 41
clojure: 23611 ms
nodejs: 9079 ms
Примечание. Я использую (время (fib 40)) в clojure, поэтому игнорирует время загрузки для JVM. Они запускаются на MacBook Air (1,86 ГГц Intel Core 2 Duo).
Итак, что заставляет clojure быть медленным здесь? И почему люди говорят, что "Clojure быстро"?
Спасибо заранее и пожалуйста, никаких пламенных войн.