2024 年 Clojure 状态调查中分享您的想法!

欢迎!请参阅关于页面了解有关此内容的更多信息。

0
ClojureScript
当生成源映射时,我们发出很多不需要的额外数据,这些数据对于映射堆栈跟踪并不需要。

Planck 在保持能够成功映射堆栈跟踪的同时,删减了大量的此类信息,从而大大提高了性能:Planck 立即加载较小的源映射文件,而不是数秒。这已经有一年历史,并且没有出现问题的报告。

我想,我们可能在编写 ClojureScript 真正的源映射时做同样的事情。尝试一个实验是有意义的,其中我们可以选择性地使用为 Planck 开发的函数移除此信息,这里为此提供了参考


(defn- strip-source-map
  "将源映射简化到映射堆栈跟踪所需的最小表示形式"
  stacktraces。这意味着我们只需要 :line 和 :col 字段,我们只需要
  每个映射向量中的最后一个元素,我们可以消除
  重复项,取每个唯一值的最大的 col 号码。"
  [sm]
  (into {}
    (map (fn [[row cols]]
           [row (->> cols
                   )(map (fn [[col frames]]
                   [col [(select-keys (peek frames) [:line :col])]]))
                  (sort-by first)
                  (distinct-by second)
                  (into {}))]))
    sm))

4 个答案

0
by

评论者:mfikes

我们目前正在为每个 AST 发出源映射行/列信息,无论操作类型如何。虽然这保证了我们拥有完整的源映射信息,但对于许多常见的用途,这可能是一个比我们需要的更大的集合。

一些操作类型可以明确省略,例如 {{:no-op}}。通过一些实验,你会发现,仅使用两种或三种操作类型,就可以实现以映射堆栈跟踪为限制目的的源映射。Dirac DevTools会更广泛地使用源映射信息,以正确识别源代码中的局部变量、绑定形式等。

所附补丁将源映射行/列的发射限制在需要映射堆栈跟踪的标签上,以及一些简单的Dirac使用场景(这需要比映射堆栈跟踪更多的操作)。这种策略的基本问题在于,我们需要确定哪些操作符子集要发射行/列信息。

但是,如果我们能够成功找到符合一般需求的最小集合,这样做可能就值得。通过所附补丁,以非并行模式编译Coal Mine时,相对于当前主分支,我们获得了12%的性能提升。

使用此补丁后,写入磁盘的源映射大小更小:对于 {{cljs.core}} 为432567字节,而不是640411字节。

附加此补丁供反馈。如果我们能找到一个合适的子集,这可能会奏效。如果这证明太困难,也许可以引入一个编译器选项来控制是否发射足够映射堆栈跟踪的小型子集或用于调试(Dirac)的稍大一些的子集,或者所有操作。

0

评论者:darwin

Dirac以两种方式依赖于源映射
1) 间接:标准的Chrome DevTools(或V8)代码在多个地方使用源映射(例如,将控制台消息行/列信息映射回原始来源,或显示调试器中的正确行,映射调试器中的局部变量名称等)
2) 直接:Dirac使用DevTools中的源映射信息,在它的REPL提示符中提供代码完成(它依赖于源映射规范中定义的“名称”列表(链接:1)

我对#2有很好的测试覆盖率,因此我会注意到代码完成方面的任何回归。但我不知道剪枝源映射会如何影响DevTools/V8本身。

另外,请注意,DevTools与ClojureScript(或其他转换语言)相关的源映射已知存在问题。Dirac试图修补这些修补程序,但可能仍有悬而未决的错误。
https://github.com/binaryage/dirac/issues/53

你了解 https://github.com/sokra/source-map-visualization 吗?这个工具在调试Dirac中的源映射问题时很有帮助。我认为这可以用来确定如何生成包含相关信息的最小源映射。

(链接:1) https://sourcemaps.info/spec.html

0

评论者:darwin

仅作记录。CLJS-2993与此相关。Mike,如果你在与ClojureScript master进行Dirac实验,你可能会受到影响。

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