我有一个 ClojureScript 程序,主要对集合执行数学计算。它是在惯用的、独立于主机的 Clojure 中开发的,因此很容易对其进行基准测试。令我惊讶的是(与答案所暗示的哪个更快,Clojure 还是 ClojureScript(以及为什么)?),ClojureScript 中的相同代码的运行速度比其 Clojure 等效代码慢 5-10 倍。
这就是我所做的。我在http://clojurescript.net/lein repl
打开了一个浏览器 repl 。然后我在两个 REPL 中都尝试了这些片段。
(time (dotimes [x 1000000] (+ 2 8)))
(let [coll (list 1 2 3)] (time (dotimes [x 1000000] (first coll))))
然后我在浏览器repl上打开了一个javascript控制台,写了一个极简的基准函数,
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 数学运算符。(这可能吗?)
- 显式使用 javascript 数组
(aget js/v 0)
- 使用不那么雄心勃勃的 clojure-for-javascript 实现,例如https://github.com/chlorinejs/chlorine或https://github.com/gozala/wisp它们生成更惯用的 javascript,但它们不支持命名空间我经常使用它。