首页 > 其他分享 >.NET8极致性能优化AOT

.NET8极致性能优化AOT

时间:2024-05-27 21:57:36浏览次数:21  
标签:Release AOT 极致 NET8 net7.0 dotnet 优化

前言

.NET8对于性能的优化是方方面面的,所以AOT预编译机器码也是不例外的。本篇来看下对于AOT的优化。原文:.NET8极致性能优化AOT

详述

首先明确一个概念,.NET里面的AOT它是原生的。什么意思呢?也就是说通过ILC编译器(AOT编译器,参考:.Net 7 新编译器 ILC 简析)编译出来的代码是各个平台上可以直接运行的二进制代码。比如MacOS的二进制,Linux二进制等等。所以称之为原生。

C#源码被ILC编译之后,生成了一个完全原生态代码的可执行文件。在执行的时候不需要JIT来编译任何东西,因为JIT已经在ILC里面被充分利用过了。实际上AOT里面也没有包含JIT。那么它如何优化呢?只能是在ILC里面调用JIT的时候了。所以它这个优化依然依靠JIT。.NET8里面优化AOT的一个典型的例子,就是ASP.NET应用程序在使用AOT的时候表现不错,同时也降低了总成本。


1.优化

在.NET8里面优化AOT的一个重要的目标就是减少AOT可执行文件的大小,关于这点的效果。我们现在就可以看到

下面创建一个控制台应用程序

dotnet new console -o nativeaotexample -f net7.0

由于上面是通过.NET7.0创建的,我们把这个控制台的csproj更改下

<TargetFramework>net7.0</TargetFramework>
改为
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>

可以轻松的构建.NET7.0或者.NET8.0的程序

继续

把<PropertyGroup>...</PropertyGroup>项中添加如下
<PublishAot>true</PublishAot>编译成AOT文件

下面我们就可以通过dotnet publish发布它了,linux如下:

dotnet publish -f net7.0 -r linux-x64 -c Release

现在它生成了一个.NET7.0版本的独立可执行文件,可通过 ls/dir 输出目录以查看生成的二进制大小

12820K /home/stoub/nativeaotexample/bin/Release/net7.0/linux-x64/publish/nativeaotexample

这个大约是13M左右,我们再来看下.NET8.0

dotnet publish -f net8.0 -r linux-x64 -c Release

生成的可执行文件大小如下:

1536K /home/stoub/nativeaotexample/bin/Release/net8.0/linux-x64/publish/nativeaotexample

1.5M的大小,这个优化的力度不可不大。优化了将近10倍的体积。这就是.NET8.0的优化魔力。


2.继续优化

但是优化的情况远不止如此,比如说我们可以配置csproj使AOT的体积更小

csproj添加如下size表示要生成的AOT大小

<OptimizationPreference>Size</OptimizationPreference>

如果我们不需要全球化代码和数据,需要特定的代码和数据,并且使用不变模式,可以csproj添加如下选项

<InvariantGlobalization>true</InvariantGlobalization>

如果你不想在AOT异常的时候抛出堆栈,那么你也可以在csproj里面添加如下

<StackTraceSupport>false</StackTraceSupport>

重新通过dotnet publish net8.0发布了之后,它的体积还可以继续减小

1248K /home/stoub/nativeaotexample/bin/Release/net8.0/linux-x64/publish/nativeaotexample

再次缩小了0.3M大小。

然而,你以为到此优化就为止了吗?并没有,.NET8不仅对AOT编译器内部进行了改进,而且还对单个库也进行了性能优化和改进。比如HttpClient。

3.其它优化

当然除了体积的优化之外,还有其它的优化,比如避免了在读取静态字段时的辅助调用,再比如BenchmarkDotNet 也是支持AOT化的,也就是性能测试上面的支持。我们可以只使用 --runtimes nativeaot7.0 nativeaot8.0,而不使用 --runtimes net7.0 net8.0,如下代码

// dotnet run -c Release -f net7.0 --filter "*" --runtimes nativeaot7.0 nativeaot8.0

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);

[HideColumns("Error", "StdDev", "Median", "RatioSD")]
public class Tests
{
    private static readonly int s_configValue = 42;

    [Benchmark]
    public int GetConfigValue() => s_configValue;
}

上面代码可以通过如下AOT化运行

dotnet run -c Release -f net7.0 --filter "*" --runtimes nativeaot7.0 nativeaot8.0

BenchmarkDotNet 输出如下

Method	        Runtime	        Mean	    Ratio
GetConfigValue	NativeAOT 7.0	1.1759 ns	1.000
GetConfigValue	NativeAOT 8.0	0.0000 ns	0.000

可以看到即使是性能测试的Benchmark,AOT优化也是不放过的。

另外还值得一提的地方就是分层,因为AOT里面没有分层的概念。但是即时编译也就是不是AOT编译的时候,一个方法从tier0提升到tier1,方法里面的静态字段必须被初始化过了。AOT里面添加了一个快速路径检查字段是否初始化,避免一些不必要的开销。

其它的一些改进,比如AOT锁的实现方式。使用了一种混合方式,开始使用轻量级自旋锁,后面升级到使用 System.Threading.Lock 类型,这个应该会在.NET9.0里面释放出来。

欢迎加入C#12.NET8最新技术交流群

结尾

作者:jianghupt
原文:.NET8极致性能优化AOT

文章公众号(jianghupt)首发,欢迎关注。

标签:Release,AOT,极致,NET8,net7.0,dotnet,优化
From: https://www.cnblogs.com/webenh/p/18216611

相关文章

  • 通过 .NET NativeAOT 实现用户体验升级
    前言#TypedocConverter 是我先前因帮助维护monaco-editor-uwp但苦于monacoeditor的API实在太多,手写C#的类型绑定十分不划算而发起的一个项目。这个工具可以将typedoc根据TypeScript生成的JSON文件直接生成对应的C#类型绑定代码,并提供完整的JSON序列化支持,......
  • .NET 7 AOT 的使用以及 .NET 与 Go 互相调用
    目录背景C#部分环境要求创建一个控制台项目体验AOT编译C#调用库函数减少体积C#导出函数C#调用C#生成的AOTGolang部分安装GCCGolang导出函数.NETC#和Golang互调C#调用GolangGolang调用C#其他 背景其实,规划这篇文章有一段时......
  • dotnet c# samples core nativeaot NativeLibrary
     如何在System.Text.Json中使用源生成 https://learn.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json/source-generation?pivots=dotnet-8-0 https://github.com/dotnet/samples/tree/main/core/nativeaot/NativeLibrary   ......
  • centos7.9 宝塔环境安装dotnet8
    官方下载二进制文件,https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0选择对应linux然后上传到到目录,这边是随意的home/dotnet8然后执行下面的命令,提示没有文件或者文件夹,就对应创建下文件夹目录就可以。可以使用linux命令:mkdir-p/home/dotnet8mkdir-p/usr......
  • 每比特极致性价比的存储技术是如何实现单位存储成本的最小化的?
    每比特极致性价比的存储技术实现单位存储成本的最小化,主要通过存储体系结构的创新、介质应用的创新以及存储介质的突破等。下面将深入探讨这些关键技术点:存储体系结构创新新型存算分离技术:基于新型高速网络总线CXL/UB等,研究内存、存储等资源的高性能、高可靠池化共享及弹性伸......
  • 每比特极致性价比的存储技术
    每比特极致性价比的存储技术是指在确保数据存储性能和可靠性的基础上,通过技术创新和优化,实现单位存储成本的最小化。这涉及到存储体系结构的创新、介质应用的创新以及存储介质本身的突破。下面将围绕这一概念进行深入分析,探讨其研究挑战方向、关键技术点以及对未来存储技术发展......
  • 【解决方案】VMware Fusion启动报错:无法将“Ethernet0”连接到虚拟网络“:dev:vmnet8
    ✨报错提示✨解决方案使用ifconfig-a查找后的确没有该虚拟网卡参考下文问题排查过程M1安装VMwareFusion13后无法连接虚拟网络/dev/vmnet8问题解决-知乎(zhihu.com)最终解决方案如下:卸载VMwareFusion关闭Clash/ClashPro增强模式重新安装VMwareFusion✨参考及......
  • .NET8 Identity Register
    分享给需要帮助的人:记一次IdentityAPI中注册的源码解读:设置用户账户为未验证状态,以及除此之外更安全的做法:延迟用户创建。包含了对优缺点的说明,以及适用场景。在ASP.NET8Identity中注册API的源码如下:routeGroup.MapPost("/register",asyncTask<Results<Ok,ValidationP......
  • .net8 winform程序使用EntityFrameworkCore连接数据库
    在.NET8WinForms应用程序中使用EntityFramework(EF)Core,你需要按照以下步骤操作:1.添加EntityFrameworkCoreNuGet包。2.定义你的数据模型。3.创建数据库上下文(DbContext)。4.在数据库上下文中配置EntityFramework。5.使用EntityFrameworkCore的API来执行数据库操作。......
  • Net8 webAPI 创建(傻瓜式入门)
    前沿学不止境(还是用windows学习吧mac太不友好了)让我来新建个Net8webapicore 然后看到这个页面选择不适用顶级语句然后配置你的目录  然后打开vsstudio看到编辑页面 可以在controllers里面创建新的.cs请求比如我新建了firstController  写入ge......