Друг дал мне этот фрагмент кода в Clojure
(defn sum [coll acc] (if (empty? coll) acc (recur (rest coll) (+ (first coll) acc))))
(time (sum (range 1 9999999) 0))
и спросил меня, как это связано с аналогичной реализацией Scala.
Код Scala, который я написал, выглядит следующим образом:
def from(n: Int): Stream[Int] = Stream.cons(n, from(n+1))
val ints = from(1).take(9999998)
def add(a: Stream[Int], b: Long): Long = {
if (a.isEmpty) b else add(a.tail, b + a.head)
}
val t1 = System.currentTimeMillis()
println(add(ints, 0))
val t2 = System.currentTimeMillis()
println((t2 - t1).asInstanceOf[Float] + " msecs")
Нижняя строка: код в Clojure работает примерно на 1,8 секунды на моей машине и использует менее 5 Мбайт кучи, код в Scala работает примерно через 12 секунд и 512 Мбайт кучи недостаточно (это завершает вычисление, если я устанавливаю кучу в 1 ГБ).
Итак, мне интересно, почему Clojure намного быстрее и стройнее в этом конкретном случае? У вас есть реализация Scala, которая имеет аналогичное поведение с точки зрения скорости и использования памяти?
Пожалуйста, воздержитесь от религиозных замечаний, моя заинтересованность заключается в том, чтобы выяснить, в первую очередь, что делает Clojure настолько быстрым в этом случае и если есть более быстрая реализация алгоритма в scala. Спасибо.