在过去二十年里,C# 靠着顺手的语法和强大的运行时,成了企业级开发的主力。它的性能优势很大程度上依赖 JIT(Just-In-Time)编译器------这东西在运行时把中间语言(IL)实时编译成机器码,能根据实际运行情况做优化。但到了 2026 年,.NET 10 全面拥抱 Native AOT(Ahead-of-Time Compilation,提前编译),这个老套路正在被改写。
在实时 AI 推理、大规模容器集群这些场景里,"够快"已经不够用了。当你部署上千个实例时,哪怕每个多占一兆内存,加起来都是笔不小的开销。Native AOT 的思路很简单:在发布阶段直接生成原生机器码,把 JIT 的活儿提前干完。这样一来,启动快了、体积小了、安全性也高了,成了现代云原生应用的一个关键选项①。
传统 JIT 模型 vs Native AOT 模型
传统 JIT 模型
-
流程:C# 代码 → IL(中间语言)→ 运行时 JIT 编译 → 机器码
-
优势:支持动态优化、反射、运行时代码生成
-
劣势:
-
启动有延迟(得等 JIT 编译)
-
内存占用更高(得保留 IL 和 JIT 相关的状态)
-
攻击面更大(JIT 引擎本身也可能成为被攻击的目标)②
-
Native AOT 模型
-
流程:C# 代码 → 发布时直接编译 → 原生可执行文件
-
优势:
-
零启动延迟:进程一启动就直接跑机器码
-
体积缩小 50% 以上:去掉了 JIT、冗余元数据和没用的代码
-
更安全:没有 JIT 引擎,攻击面自然就小了
-
-
限制:不支持动态代码生成,部分反射功能受限③
性能基准测试:Native AOT 实战对比
想看看实际差别有多大?可以跟着下面这几步,自己动手搭个对比项目试试。
1. 创建解决方案
dotnet new sln -n AOTPerformanceDemo
dotnet new console -n JitApp # 标准 JIT 应用
dotnet new console -n AotApp # Native AOT 应用
dotnet sln add JitApp AotApp
2. 添加计算负载(两个项目共用这段代码)
// Program.cs
using System.Diagnostics;
Console.WriteLine("App starting...");
var sw = Stopwatch.StartNew();
var result = HeavyComputation();
sw.Stop();
Console.WriteLine($"Result: {result}");
Console.WriteLine($"Execution Time: {sw.ElapsedMilliseconds} ms");
static long HeavyComputation()
{
long sum = 0;
for (int i = 0; i < 10_000_000; i++)
sum += i;
return sum;
}
3. 启用 Native AOT(只改 AotApp 的项目文件)
<!-- AotApp.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<PublishAot>true</PublishAot> <!-- 启用 Native AOT -->
<PublishTrimmed>true</PublishTrimmed> <!-- 裁剪没用的代码 -->
<InvariantGlobalization>true</InvariantGlobalization> <!-- 去掉全球化支持,进一步减体积 -->
</PropertyGroup>
</Project>
4. 构建与发布
# 构建 JIT 应用
dotnet build JitApp -c Release
# 发布 Native AOT 应用(这里以 Windows x64 为例)
dotnet publish AotApp -c Release -r win-x64
5. 写个简单的 Benchmark 跑一下
// BenchmarkRunner/Program.cs
using System.Diagnostics;
RunTest("JIT App", @"..\JitApp\bin\Release\net10.0\JitApp.exe");
RunTest("Native AOT App", @"..\AotApp\bin\Release\net10.0\win-x64\publish\AotApp.exe");
static void RunTest(string name, string path)
{
var sw = Stopwatch.StartNew();
var process = Process.Start(new ProcessStartInfo(path)
{
RedirectStandardOutput = true,
UseShellExecute = false
});
process.WaitForExit();
sw.Stop();
Console.WriteLine($"{name}: {sw.ElapsedMilliseconds} ms");
}
6. 看看结果
在普通硬件上跑,结果大概是这样:
-
JIT 应用:132 毫秒
-
Native AOT 应用:82 毫秒

也就是说,**Native AOT 把启动和执行时间缩短了约 60%**。而且它生成的可执行文件通常只有几 MB,而标准 JIT 应用动不动就超过 20MB④。
适用场景与限制
哪些场景特别适合 Native AOT
-
Serverless / FaaS:冷启动慢的话,函数响应就慢,这个场景对启动速度尤其敏感
-
CLI 工具:命令行工具要求"一敲就响应",不能等 JIT 热身
-
边缘设备:IoT、嵌入式设备资源有限,内存和存储都得省着用
-
安全敏感的应用:去掉 JIT 引擎,攻击面自然就小了,适合金融、政府类系统⑤
用之前得知道的一些限制
-
反射受限 :只支持编译时能确定的类型,如果要用那些动态反射,得通过
rd.xml配置文件告诉编译器保留 -
不能动态生成代码 :比如
Emit、表达式树编译这些,在 Native AOT 里用不了 -
平台相关 :发布的时候必须指定目标平台,比如
linux-x64或者win-arm64,不能一个文件到处跑
结语
Native AOT 不是来取代 JIT 的,它给 .NET 提供了一条面向极致性能和安全的新路子 。在 .NET 10 里,这套工具链已经比较成熟了,开发者在项目文件里加一行 <PublishAot>true</PublishAot>,就能拿到实实在在的好处。对于新项目,特别是云原生、边缘计算或者命令行工具,Native AOT 应该优先考虑。
参考资料
① Microsoft. .NET 10 Native AOT Documentation . https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/
② Ben Watson. Writing High-Performance .NET Code . 2nd ed., 2018.
③ Microsoft. Trimming in Native AOT . https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/
④ Microsoft. Performance Improvements in .NET 10 . https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-10/
⑤ AWS. Optimizing .NET Serverless Applications with Native AOT. https://aws.amazon.com/blogs/developer/