javascript - ClojureScript 数组性能是否需要 mod - 或者只是关于边界检查?

标签 javascript arrays clojurescript modulus

Lau Jensen has this fantastic post关于使用数组从 ClojureScript 获得高性能。他使用的技术之一是使用 mod 函数的数组 get 函数,如下所示:

(defn mod [x m]
  (js* "((x%m)+m)%m"))

(defn get-cell
  [b x y]
  (js* "b[brianscript.core.mod(y,90)][brianscript.core.mod(x,90)]"))

mod 函数在 JavaScript 中是否做了任何特殊的事情 - 或者这只是 Lau 没有在其他地方进行边界检查并将其包含在他的 get 函数中?

我的问题是:ClojureScript 数组性能是否需要 mod - 或者只是关于边界检查?

最佳答案

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 虚拟机正在对 cljs.core.mod 进行去优化,因为在程序的整个生命周期中使用不一致类型的参数来调用它。通过“克隆” mod 函数并始终使用小 int 参数调用它,虚拟机可能能够更好、更一致地优化它。但这只是猜测。

他的文章中有很多地方是完全错误的。在许多情况下,他似乎错误地将 java/clojure 推理应用于 javascript/clojurescript(毕竟他是从 Clojure 移植此应用程序)。例如,他关于使用多维数组的部分引用了Java字节码来论证javascript多维数组会更快,这完全是不正确的。 (JS 中没有多维数组——也许某些 JS VM 会优化这种情况,但唯一知道的方法就是测量。)在另一个地方他说:

The real value here [of using numbers instead of keywords], is that it allows us to use an int-array, which performs roughly 10-12% faster than a non-typed array.

在 clojurescript 中,int-array(以及所有 *-arraymake-array 函数)是普通 JavaScript 数组的别名。在 Clojure 中,它们生成不同类型的 Java 原始数组,但在 Clojurescript 中,它们都只是 new Array()。他的性能得到了提升,因为他消除了比较关键字对象而不是数字的开销,并且可能是因为他的虚拟机在幕后使用更紧凑的数组表示,因为它注意到它充满了小整数而不是指针。/p>

优化 JavaScript 性能极其困难。您必须使用真实的输入和调用模式在多个浏览器中对每个更改进行基准测试。不同的虚拟机会以不同的方式优化不同的方法,并且很少有始终有效的经验法则。关于优化 js 的一本好书是 Javascript performance for madmen ,这实际上只是让您体验到 JS 性能是多么不可预测。您还应该阅读David Nolen's post on optimizing clojurescript Jensen 引用了这一点(David Nolen 是 Clojurescript 的主要开发人员和维护人员)。

关于javascript - ClojureScript 数组性能是否需要 mod - 或者只是关于边界检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26824081/

相关文章:

integer - clojurescript `and` 整数函数的行为令人困惑

javascript - 如何使用 jQuery 加载变量中的页面内容

java - 分而治之 - 未排序数组的 k 元素

clojure - clojurescript 原子的哪些更改会导致试剂组件重新呈现?

c++ - 为什么我的if else语句不起作用并从数组中输出正确的索引?

Java foreach 与多变量数组的子集

Clojure(脚本)静态协议(protocol)?

javascript - 更改drawCallback数据表中行的背景

javascript - Google Web Search API - XMLHttpRequest 无法加载资源

javascript - 发表 Facebook 评论后重定向至网页