F# 工具链性能

为了降低构建和编辑器开销,F# 11 会共享已导入的库,并避免重复分析。 衡量受影响的工作负载,而不是假设整个版本范围内的速度或内存改进。

导入的二进制库共享功能

FSharp.Compiler.Service 可以在使用相同二进制依赖项的项目之间共享符合条件的导入库图。 FSharpChecker.Create 默认公开 shareImportedAssemblies,并默认启用。 这可避免为每个项目保留完全独立的导入图。

共享需要匹配解析的依赖项和导入设置。 排除 Project 引用、类型提供程序、多模块程序集和不明确的依赖关系闭包。 框架导入已被共享。

实现该功能的 PR 在检查并保存所有项目后,测量了保留内存。 它的十个项目 ReSharper.FSharp 工作负载在没有这种共享时使用了 1,547.2 MB,启用后使用了 1,002.2 MB。 其编译器解决方案工作负载仅变化了 0.1%。 这些是特定于更改的试验,而不是普遍的升级收益。 大型 二进制 引用中的重叠解释了大部分差异。

保留元数据与临时分配

F# 11 通过延迟创建、较小的表和重复使用来减少 保留的元数据 。 另外, 元数据读取 和内联专用化分配的临时数据较少。 保留的堆、分配量和进程内存是不同的指标;不要添加这些重叠试验的结果。

编辑器分析和导航

以下改进适用于不同的层:

组分 已避免或受限的工作
Visual Studio诊断 在考虑文本和项目版本、路径及选项的情况下,重用未更改文档的诊断结果。 这针对重复的空闲分析,而不是任意过时结果的重用。
Visual Studio查找所有引用和重命名 限制并发类型检查,而不是一次性为每个文档启动一个,同时保留取消。
外部符号引用搜索 跳过未引用该符号的二进制程序集的项目。
FCS 增量分析 同步构建器状态,以便并发请求不会针对同一变更构建重复的分析链。

Peek 修复可避免元数据导航死锁。 对生成的元数据签名使用“转到定义”;“速览”则停留在现有文档处。 这些改进需要更新编辑器/FCS 组件,而不仅仅是应用程序的核心包。

编译和生成任务并发

并行编译在 F# 11 中默认利用独立的文件和编译器各阶段的工作进行并行处理。 源排序仍然是语言的一部分;并行度不会使转发依赖项合法化。

生成任务还使用 MSBuild 的每任务环境和路径设施,而不是更改进程全局状态。 重载缓存可减少重复解析,而带守卫的模式编译可避免某些析取/守卫组合中的重复膨胀。

比较所需的指标

  • 对于生成延迟,请将等效的完整生成与相同的优化、确定性输出、引用和缓存设置进行比较。 使用 --parallelcompilation- 进行受控比较。
  • 对于保留的分析内存,请使相同的项目保持活动状态,并将实时托管内存与分配量和进程内存区分开来。
  • 对于响应性,请重现编辑器操作或空闲负载。 控制台程序的输出并不能衡量编辑器所做的工作。

另请参阅