请参与2024年Clojure状态调查,分享您的看法!2024 State of Clojure Survey!

欢迎!请查看关于页面以了解更多关于此网站的信息。

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
by

评论者:mfikes

注意,Chris已提交CA(与@hlprmnky相同 https://twitter.com/hlprmnky/status/1043661374830911489

0
by

评论者:cjbidler

包含变更的补丁,所有测试通过。

0
by

评论者:mfikes

Chris,请附上一个修订过的补丁,不要更新* }的{{def}}。(您可以将其命名为CLJS-2920-2.patch,并且应该是一个独立的补丁,不依赖于之前的补丁。)

0
by

评论者:cjbidler

按指示修改;谢谢提醒这个。为了今后参考,在运行lein uberjar后,重置那句def是手动清理步骤吗?如果有自动化的东西可以防止我将来补丁提交中的这种错误,我将非常乐意了解有关信息。:D

0
by

评论者:mfikes

我不知道有自动化的清理* }修订的机制。我通常只是尽力避免在提交中尝试该特别变更。

0
by

评论者:mfikes

CLJS-2920-2.patch 通过 LGTM 并通过了所有甘露测试。

0
by

评论者:mfikes

CLJS-2920-2.patch 不再适用

0
by

评论者:mfikes

实际上,如果你包括了 {{3way}} 选项,补丁就可以正常应用,不需要重新基线化。

0
by
参考资料:[CLJS-2920](https://clojure.atlassian.net/browse/CLJS-2920) (由 mfikes 报告)
...