gpt4 book ai didi

performance - 如果有的话,我怎样才能提高我在 Clojure 中的数值性能?

转载 作者:行者123 更新时间:2023-12-04 03:05:38 24 4
gpt4 key购买 nike

这是一个简短的 Scala 程序,它通过生成一堆随机数来计算欧拉数的近似值:

package example

import scala.util.Random

object ApproxE extends App {

def calc = {
var S = 0.0
for {i <- 1 to 100000000} {
var x = 0.0
var t = 0
while (x <= 1.0) {
x += Random.nextDouble
t += 1
}
S += t
}
S / 100000000
}

val st = System.currentTimeMillis()
val e = calc
val ed = System.currentTimeMillis()

println(e)
println(ed - st)

}

在我的笔记本电脑上运行,它在大约 7 秒内完成计算。

以下是两个等效的 Clojure 函数。 On 在 48 秒内返回,另一个在 230 秒内返回。

是否有可能在纯 Clojure 中编写具有与 Java 或 Scala 可实现的性能相当的程序?

48 秒:
(defn calc []
(loop [i (int 0)
S (double 0.0)]
(if (= i 100000000)
(/ S 100000000)
(let [rs (repeatedly rand)
ps (reductions + rs)
<=1 #(<= % 1)]
(->> ps
(take-while <=1)
(count)
(inc)
(+ S)
(recur (inc i)))))))

230 秒:
(defn calc2 []
(with-local-vars [S 0.0]
(dotimes [i 100000000]
(with-local-vars [x (double 0)
t (int 0)]
(while (<= @x 1)
(var-set x (+ @x (rand)))
(var-set t (inc @t)))
(var-set S (+ @S @t))))
(/ @S 100000000)))

最佳答案

惰性数据结构和本地变量都会由于分配而引入开销(尽管您仍然可以通过将 xt 的分配移出循环来使带有变量的变量更快一点),名称解析(以防万一vars) 和方法调用。

Scala 代码的逐字翻译将使用本地绑定(bind)(使用 letloop ),它们等效于 Java 的局部变量:

(defn calc-loops []
(loop [i (int 0)
S (double 0.0)]
(if (= i 100000000)
(/ S 100000000)
(recur
(inc i)
(loop [t 0 x 0.0]
(if (<= x 1.0)
(recur (inc t) (+ x (rand)))
(+ S t)))))))

(time (calc)) ;; => "Elapsed time: 56255.692677 msecs"
(time (calc-loops)) ;; => "Elapsed time: 8800.746127 msecs"

关于performance - 如果有的话,我怎样才能提高我在 Clojure 中的数值性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52601368/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com