请在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
by

被:mfikes发表的评论

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

0
by

被:cjbidler发表的评论

与票中概述的更改一致的改变补丁。所有测试都通过。

0
by

被:mfikes发表的评论

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

0
by

被:cjbidler发表的评论

按照要求操作;感谢你指出这一点。为了将来参考,将那个def重置是否是运行lein uberjar之后的手动清理步骤?如果有一个可以自动执行以保护我在将来补丁提交中避免这种错误的方法,我将很高兴知道。 :D

0
by

被:mfikes发表的评论

我不了解自动清理* }修订的方法。我通常只是尽量避免在提交中提出这个特定的更改。

0

被:mfikes发表的评论

CLJS-2920-2.patchLGTM并且通过了所有Canary测试。

0

被:mfikes发表的评论

CLJS-2920-2.patch不再适用

0

被:mfikes发表的评论

实际上,如果包括 {{--3way}} 选项,补丁可以很好地应用,因此不需要重新基准测试。

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