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)))


我们看到总速度提升接近无限大(该操作实际上变得免费,与基准相同的时间)。

请注意,我们或许可以使用由此处表达式触发的短路的 {{&&}} 的 optimized {{js*}} 输出,并使用一个新宏而不是 predicated-induced 类型推断来代替,但 CLJS-2866 目前取决于查看悲伤的 {{if}} 测试,而像这样的表达式会导致 optimized {{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

评论者:mfikes

CLJS-2920-2.patch 已不再适用

0

评论者:mfikes

实际上,如果包含 {{--3way}} 选项,修复程序将适用良好,因此无需重新基准测试。

0
参考:https://clojure.atlassian.net/browse/CLJS-2920(由 mfikes 提出)
...