2024 Clojure调查中分享您的想法!

欢迎!请参阅关于页面了解该工作原理的更多信息。

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

可以进行两种独立的优化。

在 {{boolean}} 用于({{qualified-}} 函数)的地方,我们可以使用 {{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

克里斯,请附上一个修改版的补丁,不要更新 {{def}} for * }。(您可以命名为CLJS-2920-2.patch,并且它应该是一个独立的补丁,不依赖于之前的补丁。)

0 投票

评论者:cjbidler

照指示做了;谢谢你指出这一点。为了以后参考,在运行 lein uberjar 之后重置那个 def 是一个手动清理步骤吗?如果有我可以自动完成的操作来避免未来补丁提交中的这个错误,我会很高兴知道的。:D

0 投票

评论者:mfikes

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

0 投票

评论者:mfikes

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

0 投票

评论者:mfikes

CLJS-2920-2.patch不再适用

0 投票

评论者:mfikes

实际上,如果你包括{{--3way}}选项,补丁应用程序良好,因此无需重新基准。

0 投票
参考: https://clojure.atlassian.net/browse/CLJS-2920(由mfikes报告)
...