为了降低构建和编辑器开销,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-进行受控比较。 - 对于保留的分析内存,请使相同的项目保持活动状态,并将实时托管内存与分配量和进程内存区分开来。
- 对于响应性,请重现编辑器操作或空闲负载。 控制台程序的输出并不能衡量编辑器所做的工作。