Performance 如何使阶乘更快?
我用Clojure做了一个简单的阶乘程序Performance 如何使阶乘更快?,performance,algorithm,clojure,Performance,Algorithm,Clojure,我用Clojure做了一个简单的阶乘程序 (defn fac [x y] (if (= x 1) y (recur (- x 1) (* y x))) ) (def fact [n] (fac n 1)) 怎样才能做得更快?如果可以用更快的方法来完成。您可以在这里找到许多快速阶乘算法: 如上所述,Clojure并不是最好的语言。考虑使用C、C++、FORTRAN、 请小心使用的数据结构,因为阶乘增长非常快。您可以在这里找到许多快速阶乘算法: 如上所述,Clojure并不是最好的语
(defn fac [x y]
(if (= x 1) y (recur (- x 1) (* y x)))
)
(def fact [n] (fac n 1))
怎样才能做得更快?如果可以用更快的方法来完成。您可以在这里找到许多快速阶乘算法: 如上所述,Clojure并不是最好的语言。考虑使用C、C++、FORTRAN、
请小心使用的数据结构,因为阶乘增长非常快。您可以在这里找到许多快速阶乘算法: 如上所述,Clojure并不是最好的语言。考虑使用C、C++、FORTRAN、
请小心使用的数据结构,因为阶乘增长非常快。借助您自己的
fact
函数(或任何其他函数),我们可以定义这个极快的版本:
(def fact* (mapv fact (cons 1 (range 1 21))))
这将为常数时间范围为1到20的参数提供正确的结果。超出该范围,您的版本也不会给出正确的结果(即,(事实21)
)存在整数溢出)
编辑:这里有一个改进的实现,它不需要另一个事实
实现,不会溢出,并且在定义过程中应该更快,因为它不会从头开始计算其查找表中的每个条目:
(def fact (persistent! (reduce (fn [v n] (conj! v (*' (v n) (inc n))))
(transient [1])
(range 1000))))
编辑2:对于不同的快速解决方案,即在不建立查找表的情况下,最好使用已经高度优化的库。谷歌的通用工具库Guava包含一个阶乘实现
通过添加此Leiningen依赖项将其添加到项目中:
[com.google.guava/guava“15.0”]
。然后,您需要(导入com.google.common.math.bigingermath)
,然后可以使用(bigingermath/factorial n)
调用它。借助于您自己的fact
函数(或任何其他函数),我们可以定义这个极快的版本:
(def fact* (mapv fact (cons 1 (range 1 21))))
这将为常数时间范围为1到20的参数提供正确的结果。超出该范围,您的版本也不会给出正确的结果(即,(事实21)
)存在整数溢出)
编辑:这里有一个改进的实现,它不需要另一个事实
实现,不会溢出,并且在定义过程中应该更快,因为它不会从头开始计算其查找表中的每个条目:
(def fact (persistent! (reduce (fn [v n] (conj! v (*' (v n) (inc n))))
(transient [1])
(range 1000))))
编辑2:对于不同的快速解决方案,即在不建立查找表的情况下,最好使用已经高度优化的库。谷歌的通用工具库Guava包含一个阶乘实现
通过添加此Leiningen依赖项将其添加到项目中:[com.google.guava/guava“15.0”]
。然后您需要(导入com.google.common.math.BigIntegerMath)
,然后可以使用(BigIntegerMath/factorial n)
调用它
(defn fact [n] (reduce *' (range 1 (inc n))))
'告诉Clojure透明地使用BigInteger以避免溢出 以下是我最喜欢的:
(defn fact [n] (reduce *' (range 1 (inc n))))
'告诉Clojure透明地使用BigInteger以避免溢出 首先,如果你需要快速的东西,不要使用Clojure尝试将
x
和y
注释为int。此外,您可能对Clojure中的简单性能优化感兴趣。一个实用的建议是不要使用阶乘。例如,如果您想要n/(n-k)代码>,您可以在单个循环/递归中处理它,而无需计算n代码>或(n-k)代码>,这样做既快又可靠(不太可能溢出)。使用阶乘函数作为构建块很少是一个好主意,因为它增长如此之快(在溢出32位整数IIRC之前只有13个不同的阶乘)。好吧,对于初学者来说,如果需要快速的东西,不要使用Clojure。;-)尝试将x
和y
注释为int。此外,您可能对Clojure中的简单性能优化感兴趣。一个实用的建议是不要使用阶乘。例如,如果您想要n/(n-k)代码>,您可以在单个循环/递归中处理它,而无需计算n代码>或(n-k)代码>,这样做既快又可靠(不太可能溢出)。使用阶乘函数作为构建块很少是一个好主意,因为它增长如此之快(在溢出32位整数IIRC之前只有13个不同的阶乘)。哪里记录了*?这里:哪里记录了*?这里: