Я новичок в Clojure. В эксперименте с ним я написал функцию I для вычисления n!
. Мой код Clojure выглядит следующим образом:Низкая производительность факториальной функции, написанной на Clojure
(defn factorial
[n]
(reduce * (biginteger 1) (range 1 (inc n))))
Затем я запустил следующее в реплике.
(time (factorial 100))
И это был результат:
"Elapsed time: 0.50832 msecs"
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000N
Затем я создал подобное решение в Ruby:
def factorial(n)
start = Time.now.to_f
(2..n).inject(1) { |p, f| p * f }
finish = Time.now.to_f
time_taken = finish - start
puts "It took: #{(time_taken * 1000)} msecs"
end
с IRB я побежал factorial(100)
Результирующее в:
It took: 0.06556510925292969 msecs
=> 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Производительность версии Ruby, по-видимому, значительно выше, несмотря на большинство доказательств, которые я видел, предполагая, что Clojure должен иметь превосходную производительность. Есть ли что-то, что я недопонимаю или какой-то элемент моего решения Clojure, который замедлит его?
Попробуйте использовать 'bigint' вместо' biginteger'. – ndn
Да, это сработало bigint, сделав выполнение намного быстрее. –
Использование 'time' в этом тесте серьезно вводит в заблуждение из-за того, как JVM« разогревает »функции. Пример clojure на самом деле * намного быстрее, чем рубиновый, если вы принимаете определение дизайнеров Java Platform «fast» как «быстро, как только оно разогревается, чтобы скомпилироваться» –