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


我们看到总速度提升接近无限(操作基本上变得免费,与基准用时相同)。

注意,我们也许可以使用由断言引起的类型推理以及一个发射{{.-ns}}的新宏的{{namespace}},但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是一个清理步骤吗?如果有一个自动化方法可以防止我在未来的补丁提交中犯这个错误,我将非常乐意了解。 :D

0

评论者:mfikes

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

0

评论者:mfikes

CLJS-2920-2.patch LGTM并所有金丝雀测试通过。

0

评论者:mfikes

CLJS-2920-2.patch不再适用

0

评论者:mfikes

实际上,如果包含{{--3way}}选项,补丁将适用良好,因此无需重新建立基线。

0
...