2024 Clojure 状态调查!中分享你的想法。

欢迎!请参见关于页面了解更多关于如何使用本服务的信息。

0
ClojureScript
对于以下函数,我们有针对 {{simple-ident?}}, {{qualified-ident?}}, {{simple-symbol?}}, {{qualified-symbol?}}, {{simple-keyword?}}, 和 {{qualified-keyword?}} 的优化措施。

可以单独进行两次优化。

在 {{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);
}


(这个修改后的实现的紧凑性意味着它可能可以通过 Closure 进一步内联以获得更多的速度优化。)

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
by

评论人:mfikes

CLJS-2920-2.patch不再适用

0
by

评论人:mfikes

实际上,如果包含{{3way}}选项,补丁可以正常应用,因此无需重新制定基线。

0
by
...