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

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](https://clojure.atlassian.net/browse/CLJS-2920)(由mfikes报告)
...