.NET 中备受追捧和期待已久的功能NativeAOT终于出现在本周的.NET 7 预览版2中,该项目的工作仍在继续,该版本将 NativeAOT 从实验性的 dotnet/runtimelab repo 中移出合并进入稳定的运行时库 dotnet/runtime repo,但尚未在 dotnet SDK 中添加足够的支持,以使用 NativeAOT 发布项目。完成此操作后,可以对实际测试进行完善了。
.NET NativeAOT 编译器脱离实验性质正式跟随 .NET 7 Preview 2 发布到了官方 nuget 源:https://www.nuget.org/packages/Microsoft.DotNet.ILCompiler 。
从现在开始,7.0.0-* 版本基本可以放心用在生产环境。我们可用开始尝试修剪我们的应用程序,并确保没有剪裁警告。剪裁是 NativeAOT 的要求。GitHub 问题 .NET 7 中的 NativeAOT #61231 显示了正在检查的初始工作以及第一阶段的剩余工作:
NativeAOT 这个功能的完整支持真是不容易,具体怎么用可用参考 hez2010的文章:通过 .NET NativeAOT 实现用户体验升级。
这里来回顾一下这个历程:具体内容来自知乎的hez2010 的整理的内容 https://www.zhihu.com/question/472875939 :
Native AOT (2021.1~2021.7)的进展:
托管类型系统的完善,支持了泛型接口的默认方法实现,但是还是不支持接口的泛型默认方法实现,因为这部分要对类型系统做很多的改动。
COM 支持基本做完了,因此现在的 Native AOT 已经可以成功编译和运行 winforms 程序了(需要 COM Wrapper),WPF、WinUI 和 UWP 也在实验中,但是 WPF 涉及到 C++/CLI,这部分无法静态链接进去,不太可能获得 Native AOT。
泛型虚方法懒实例化(GVM Instantiation),不需要在编译的时候就实例化所有的泛型虚方法,而是留在运行时第一次调用时来做,这么做不仅不会损失性能,而且还能节省大量的编译后体积,并避免泛型虚方法递归实例化导致的编译时无限递归展开问题。但是并没有完全解决无限泛型递归的问题,由于并行编译没法使用强联通分量算法进行检测。
支持了动态调用标注,然后对 .NET 6 的 BCL 进行了标注,因此大多数情况即使基础库某些方法里用到了反射创建类型,也不会出现运行时找不到代码的问题,因为框架自己做了标注,编译的时候编译器就能知道并生成代码,而无需人工编写大量的 rd.xml 标注信息。
目前正在添加托管类型系统对静态虚方法的支持(已有 PR)。
目前正在添加对 PS4/PS5 等平台的支持(缓慢进展,可以运行起来简单程序了)。
目前正在添加对 WASM 平台的支持(缓慢进展,可以运行起来简单程序了)。
支持了 ARM64 平台。
支持了静态链接依赖项。
支持使用 .NET 6 的静态 PGO 数据做优化编译。
编译速度的改善也是能明显看得到的,以前的旧版本 CoreRT 编译个程序动辄十分钟半小时,现在基本半分钟一分钟都能搞定。
2021/8/12 更新:
正在添加对 ARMv7 平台的支持(已有 PR)
正在添加对接口泛型方法默认实现的支持(已有 PR)
2021/8/14 更新:
接口泛型方法默认实现已支持,因此 efcore 可以用 NativeAOT 了
泛型虚拟方法解析速度有所提升(大概 8%),编译时间更短了
2021/8/17 更新:
NativeAOT 在 .NET 6 上计划的内容已经完成,已经可以稳定使用,另外可能会在 .NET 7 脱离实验正式发布
ARMv7 平台支持已接近完成
2021/8/24 更新:
NativeAOT 编译器版本已提升至 7.0.0-*
2021/9/6 更新:
正在适配安卓
LLVM 从 6 升级到 12
完善
IDynamicInterfaceCastable
支持,对 COM 的支持度进一步改善
2021/9/17 更新:
支持了模块初始化器
正在添加对 x86 的支持
2021/12/6 更新:
Native AOT 转正正式提上 .NET 7 计划
2021/12/15 更新:
Native AOT 代码正式合并入 .NET 主线并启用了构建
无限泛型展开导致无法编译的问题已经解决
2022/3/17 更新:
1. 正式在.NET 7 Preview 2博客文章中宣布可用。
2. WPF 开始了 AOT 改造: https://github.com/dotnet/wpf/pull/6171