2024 Clojure调查!上分享您的想法。

欢迎!请参阅关于页面以了解更多关于此内容的信息。

0
ClojureScript
对于{{simple-ident?}}、{{qualified-ident?}}、{{simple-symbol?}}、{{qualified-symbol?}}、{{simple-keyword?}}和{{qualified-keyword?}}函数,我们可以进行一些优化。

可以进行两种独立优化。

在.where {{boolean}}被使用的地方(合格的函数),我们可以改用{{some?}}以获得更快的实现


(boolean (and (symbol? x) (namespace x) true))


可以转换成简单的方式


(and (symbol? x) (some? (namespace x)))


先集中在V8上,对


(simple-benchmark [x 'a/b f #(qualified-symbol? x)] (f) 100000000)


和减去基准成本的


(simple-benchmark [x 'a/b f (fn [] x)] (f) 100000000)


得到的加速值为1.74。

由于我们知道在应用{{namespace}}时我们处理的是关键词或符号,因此我们可以进一步使用{{(.-ns x)}}。

仅此一项就提供了2.21的加速,与前面的优化结合


(and (symbol? x) (some? (.-ns x)))


我们看到综合加速接近无穷大(操作实际上变得免费,与基准花费相同的时间)。

请注意,也许我们可以使用由谓词引起的类型推理,以及一个用于{{namespace}}的新宏,该宏发出{{.-ns}},但CLJS-2866目前仍然取决于在{{if}}中查看测试,而上述类似的表达式会导致带有短路{{&&}}的优化{{js*}}输出。

这些优化将很有用,因为这些函数经常用于基于规范的生成代码测试,在这种情况下性能可能是一个问题。

我们在{{cljs.predicates-test}}中为此函数提供了测试覆盖率。

以下是为{{qualified-symbol?}}生成的当前JavaScript代码:


function cljs$core$qualified_symbol_QMARK_(x) {
  return cljs.core.boolean$(
    (function() {
      var and__8540__auto__ = x instanceof cljs.core.Symbol;
      if (and__8540__auto__) {
        var and__8540__auto____$1 = cljs.core.namespace(x);
        if (cljs.core.truth_(and__8540__auto____$1)) {
          return true;
        } else {
          return and__8540__auto____$1;
        }
      } else {
        return and__8540__auto__;
      }
    })()
  );
}


以下是经过修订得到的结果


function cljs$user$qualified_symbol_QMARK_(x) {
  return x instanceof cljs.core.Symbol && !(x.ns == null);
}


(该修订版的紧凑性意味着它可能通过闭包进一步内联,从而在程序优化中获得更多速度提升。)

9 个答案

0

由:mfikes发表的评论

注意:Chris已经提交了CA(与@hlprmnky的相同https://twitter.com/hlprmnky/status/1043661374830911489

0

由:cjbidler发表的评论

补丁包含与工单中所述的更改。所有测试通过。

0

由:mfikes发表的评论

嗨Chris,请附上一个修订的补丁,不要更新 * } 的 {{def}}。(您可以命名为CLJS-2920-2.patch,它应该是独立的补丁,不依赖于以前的补丁。)

0

由:cjbidler发表的评论

如您所指示;感谢指出这一点。作为未来的参考,重置那个 def 是运行 lein uberjar 后的手动清理步骤吗?如果有一个我可以自动执行的步骤来防止在未来补丁提交中犯这样的错误,我会很高兴知道。 :D

0

由:mfikes发表的评论

我不知道有一个自动机制来清理 * } 的修订。我通常只是尽量避免在提交中处理那个特定的更改。

0

由:mfikes发表的评论

CLJS-2920-2.patch LGTM 且通过所有Canary测试。

0

由:mfikes发表的评论

CLJS-2920-2.patch不再适用

0

由:mfikes发表的评论

实际上,如果在patch中包含{{--3way}}选项,该补丁适用无误,因此无需重新建立基线。

0
...