gpt4 book ai didi

performance - 提高 ClojureScript 程序的性能

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

我有一个 ClojureScript 程序,主要对集合执行数学计算。它是在惯用的、独立于主机的 Clojure 中开发的,因此很容易对其进行基准测试。令我惊讶的是(与答案对 Which is faster, Clojure or ClojureScript (and why)? 的建议相反),ClojureScript 中的相同代码的运行速度比其 Clojure 等效代码慢 5-10 倍。

这是我所做的。我开了一个lein repl和浏览器复制在 http://clojurescript.net/ .然后我在两个 REPL 中都尝试了这些片段。

 (time (dotimes [x 1000000] (+ 2 8)))

(let [coll (list 1 2 3)] (time (dotimes [x 1000000] (first coll))))

然后我在浏览器repl打开一个javascript控制台,写了一个极简的benchmark函数,
 function benchmark(count, fun) {
var t0 = new Date();
for (i = 0; i < count; i++) {
fun();
}
var t1 = new Date();
return t1.getTime() - t0.getTime();
}

回到浏览器REPL:
 (defn multiply [] (* 42 1.2))

然后在 javascript 控制台中尝试原生 javascript 乘法及其 clojurescript 变体,
 benchmark(1000000, cljs.user.multiply);

benchmark(1000000, function(){ 42 * 1.2 });

我发现了什么
  • 原生 javascript 数学与 clojure 中的数学相当
  • ClojureScript 比它们中的任何一个都慢 5-10 倍

  • 现在我的问题是,如何提高 ClojureScript 程序的性能?

    到目前为止我已经考虑了一些方法
  • 回退到在幕后使用可变的 javascript 数组和对象。 (这可能吗?)
  • 回退到使用原生 javascript 数学运算符。 (这可能吗?)
  • 使用 (aget js/v 0) 显式使用 javascript 数组
  • 使用一个不那么雄心勃勃的 clojure-for-javascript 实现,比如 https://github.com/chlorinejs/chlorinehttps://github.com/gozala/wisp它们生成了更惯用的 javascript,但它们不支持我经常使用的命名空间。
  • 最佳答案

    JavaScript 有显式返回,所以

    function () { 42 * 1.2 }

    什么也没做;你会想要基准
    function () { return 42 * 1.2 }

    反而。这恰好是 ClojureScript 版本编译成的结果,因此不会有任何区别(在 ClojureScript 中,非高阶使用中的基本算术函数被内联为基于常规运算符的 JavaScript 表达式)。

    现在,在这一点上,Clojure 绝对比 ClojureScript 快。部分原因是 Clojure 仍然比 ClojureScript 更仔细地调整,尽管 ClojureScript 在这个部门以相当大的速度改进。另一部分是 Clojure 有一个更成熟的 JIT 可以利用(现代 JS 引擎,尤其是 V8,非常棒,但还不是 HotSpot 级)。

    但是,差异的大小有点难以衡量。涉及 JIT 的事实意味着一个没有任何副作用的循环,例如问题中的循环,可能会被优化掉,甚至可能在第一次运行时(通过使用堆栈替换,由 HotSpot 使用,我认为也是 V8——不过我必须检查以确保)。所以,最好对类似的东西进行基准测试
    (def arr (long-array 1))

    ;;; benchmark this
    (dotimes [_ 1000000]
    (aset (longs arr) 0 (inc (aget (longs arr) 0))))

    ( longs 调用以避免在 Clojure 中反射;也可以使用 ^longs 提示)。

    最后,当然,在 Clojure 和 ClojureScript 中,对于某些类型的特别对性能敏感的代码,最好使用 native 数组等。令人高兴的是,这样做没有问题:在 ClojureScript 方面,您有 array , js-obj , aget , aset , make-array ,您可以使用 :mutable deftype 中字段的元数据能够 set!它们在方法体等中。

    关于performance - 提高 ClojureScript 程序的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16548136/

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