brianscript.core.mod() 编译成与cljs.core.mod() 完全相同的代码。这是编译好的clojurescript代码:
cljs.core.mod = (function mod(n,d){return (((n % d) + d) % d);
他对get-cell 的重新实现也是不必要的:他使用aset 的原始版本将编译为相同的javascript 代码。
他不能使用 js % 运算符(实际上发音为“余数”,而不是“模数”),因为他希望在他的邻居检查函数中进行坐标查找以“环绕”板。例如。如果他在坐标 0,并且想要检查他左边的单元格,则索引是 89,而不是 -1。 -1 % 90 = -1,但是mod(-1, 90) = 89。
如果他从编写自己的 mod 中看到了任何性能优势,那不是,因为他比 cljs.mod 更“脚踏实地”。可能 javascript vm 正在对 cljs.core.mod 进行反优化,因为在程序的整个生命周期中调用它时使用的参数类型不一致。通过“克隆” mod 函数并始终使用小的 int 参数调用它,VM 可能能够更好、更一致地对其进行优化。不过,这只是猜测。
他的文章中有很多地方是完全错误的。在许多情况下,他似乎错误地将 java/clojure 推理应用于 javascript/clojurescript(毕竟他是从 Clojure 移植此应用程序)。例如,他关于使用多维数组的部分引用 Java 字节码来论证 javascript 多维数组会更快,这完全不正确。 (JS 中没有 multidim 数组——也许一些 JS VM 会优化这种情况,但唯一知道的方法就是测量。)在另一个地方他说:
[使用数字代替关键字]的真正价值在于它允许我们使用 int 数组,它的执行速度比非类型数组快大约 10-12%。
在 clojurescript 中,int-array(以及所有*-array 和make-array 函数)是普通javascript 数组的别名。在 Clojure 中,这些生成不同类型的 Java 原始数组,但在 Clojurescript 中,它们都只是new Array()。他的性能得到了提升,因为他消除了比较关键字对象而不是数字的开销,并且可能是因为他的 vm 在底层使用了更紧凑的数组表示,因为它注意到它充满了小整数而不是指针。
优化 javascript 性能非常困难。您必须在多个浏览器中使用实际输入和调用模式对每个更改进行基准测试。不同的虚拟机会以不同的方式优化不同的方法,并且很少有经验法则总是有效的。关于优化 js 的好消息是 Javascript performance for madmen,它实际上只是让您体验到 JS 性能的不可预测性。您还应该阅读 Jensen 引用的 David Nolen's post on optimizing clojurescript(David Nolen 是 Clojurescript 的主要开发人员和维护人员)。