告别 JIT?.NET 10 Native AOT 实践指南

在过去二十年里,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/

相关推荐
无风听海4 小时前
.NET10之C# Extension Members深入分析
大数据·c#·.net·extensionmember
唐青枫4 小时前
C#.NET 分布式事务 深入解析:TCC、Saga、Outbox 与落地取舍
c#·.net
余衫马6 小时前
在 IIS 部署 .NET6 WebApi 应用
运维·c#·iis·.net·发布
无风听海6 小时前
.NET10之C# File-Scoped Namespace 深度解析
c#·.net·.net10
焚 城6 小时前
.NET8实现 文本生成摘要
.net
武藤一雄1 天前
C# 竟态条件
microsoft·c#·.net·.netcore
武藤一雄1 天前
WPF深度解析Behavior
windows·c#·.net·wpf·.netcore
极客智造1 天前
Nito.AsyncEx 详解:.NET 异步编程的瑞士军刀
.net
桑榆肖物1 天前
用 .NET 做一个跨平台的 Improv Wi-Fi 蓝牙配网项目
.net·蓝牙·iot