[翻译].NET 8 的原生AOT及高性能Web开发中的应用[附性能测试结果]

net,aot,web · 浏览次数 : 3

小编点评

本文介绍了.NET 8原生AOT(预编译)的概念及其对Web开发人员的影响。原生AOT将.NET代码直接编译为原生代码,避免了运行时的即时编译(JIT),从而提高了应用程序的性能并简化了开发过程。 .NET 8引入了名为“ASP.NET Core Web API (Native AOT)”的新项目模板,专为原生AOT设计。这个模板通过使用CreateSlimBuilder和CreateEmptyBuilder方法,提供了不同的性能和定制化选项。性能测试结果显示,CreateSlimBuilder方法在启动速度和内存占用方面优于其他两种方法,而CreateEmptyBuilder方法则提供了最快的启动速度和最低的资源消耗,但要求开发人员手动配置所有必需的服务。 总之,原生AOT的引入为Web开发带来了显著的性能优势,同时也增加了开发的复杂性。开发人员应根据项目的具体需求和性能目标,权衡这些选项。

正文

原文: [A Dive into .Net 8 Native AOT and Efficient Web Development]
作者: [sharmila subbiah]

引言

随着 .NET 8 的发布,微软迈出了重要一步,为 ASP.NET Core 引入了原生的 Ahead-of-Time (AOT) 编译。这一进步不仅提高了应用程序的性能,还简化了开发过程,标志着 .NET 生态系统进入了新的时代。

.NET 8中原生AOT的出现

.NET 8 引入了原生 AOT,这对 Web 开发人员来说是一个重大改变。该技术将 .NET 代码直接编译为原生代码,无需在运行时进行即时 (JIT) 编译。结果如何?启动时间更快、内存占用更少、以及整体改善的应用程序性能升,这对于高流量 Web API 和微服务尤其重要。

探索 ASP.NET Core Web API (Native AOT) 项目模板

.NET 8 引入了一个专门为原生 AOT 设计的全新项目模板 - "ASP.NET Core Web API (native AOT)" 项目模板。
此模板的简称为“webapiaot”,默认启用 AOT 发布。它是为希望从项目一开始就充分利用 AOT 编译潜力的开发人员量身定制的。此更新中的两个新功能是CreateSlimBuilder() 和CreateEmptyBuilder()方法。

CreateSlimBuilder 方法: 优化性能

CreateSlimBuilder 方法体现了微软致力于高性能开发的决心。它仅初始化 WebApplicationBuilder 中运行应用程序所需的基本 ASP.NET Core 功能。这个方法不仅简化了开发过程,而且确保应用程序保持轻量级和高性能。
CreateSlimBuilder 方法中包含的主要功能包括:

  • appsettings.json 和 appsettings.{EnvironmentName}.json 的 JSON 文件配置,实现强大而灵活的配置管理。
  • 集成用户机密配置,增强开发环境的安全性。
  • 内置控制台日志记录,方便直接调试和监控。
  • 全面的日志配置,为开发人员提供对应用程序行为的关键监控。
var builder = WebApplication.CreateSlimBuilder(args);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

但是,CreateSlimBuilder 这个极简方法省略了传统的 Startup.cs 文件,需要开发人员进行显式配置。它还删除了 EventLog、Debug 提供程序和 EventSource 主机 - 这些组件如果需要的话必须手动添加。还有一个比较重要的是,它没有开箱即用的 IIS、HTTPS、HTTP3 或完整的 Kestrel 服务器配置支持,需要开发人员有意添加这些功能来加强通信安全性和服务器健壮性。

这些可以通过显式添加到配置中来实现,例如看下面的示例如何实现这些自定义:

using Microsoft.AspNetCore.Routing.Constraints;

var builder = WebApplication.CreateSlimBuilder(args);

//http3 customization
builder.WebHost.UseQuic();

//Https customization
builder.WebHost.UseKestrelHttpsConfiguration();

//Regex customization
builder.Services.AddRouting().Configure<RouteOptions>(x =>
{
    x.SetParameterPolicy<RegexInlineRouteConstraint>("Regex");
});

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

CreateEmptyBuilder 方法: ** 最纯粹的定制**

.NET 8 的 CreateEmptyBuilder 方法体现了定制化的极致。它为开发者提供了一张白纸,让他们可以创造出定制化、小规模的应用程序。这反映了简单性和自主性的最高境界 - 只有开发者选择的组件才会被包含其中。

var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions
{
    Args =args
});

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

为了确保应用程序正常运行,必须手动配置每个组件。如果在没有配置的情况下尝试执行上述代码,将发生错误。下面是一个正确的例子。

using Microsoft.AspNetCore.Routing.Constraints;

var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions
{
    Args = args
});
builder.WebHost.UseKestrelCore();
builder.Services.AddRoutingCore();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

性能测试结果: .NET 8 中的 Builder 方法

using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Routing.Constraints;
using System.Collections.Generic;

namespace NewAppTypes
{
    [MemoryDiagnoser]
    public class BenchMarks
    {
        public string[]? Args { get; private set; }

        [Benchmark]
        public void CreateBuilder()
        {
            var builder = WebApplication.CreateBuilder(Args);
            var app = builder.Build();
            builder.WebHost.UseUrls("http://*:80", "https://*.443");


            app.MapGet("/", () => "Hello World!");

        }

        [Benchmark]
        public void CreateSlimBuilder()
        {
            var builder = WebApplication.CreateSlimBuilder(Args);

            //http3 customization
            builder.WebHost.UseQuic();

            //Https customization
            builder.WebHost.UseKestrelHttpsConfiguration();

            //Regex customization
            builder.Services.AddRouting().Configure<RouteOptions>(x =>
            {
                x.SetParameterPolicy<RegexInlineRouteConstraint>("Regex");
            });

            var app = builder.Build();
            builder.WebHost.UseUrls("http://*:80", "https://*.443");
            app.MapGet("/", () => "Hello World!");

        }

        [Benchmark]
        public void CreateEmptyBuilder()
        {
            var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions
            {
                Args = Args
            });
            builder.WebHost.UseKestrelCore();
            builder.Services.AddRoutingCore();

            var app = builder.Build();
            builder.WebHost.UseUrls("http://*:80", "https://*.443");
            app.MapGet("/", () => "Hello World!");

        }

    }
}

性能测试结果揭示了一些有趣的性能数据。从结果中,我们可以观察到以下内容:

  • CreateBuilder 方法: 这是用于初始化 web 应用程序的标准方法,显示平均执行时间为 2682.3 微秒(us),分配内存约为 536.26 KB。这种方法设置了完整的 web 托管环境,具有所有默认服务和配置。执行时间和内存分配反映了这种全面性。

  • CreateSlimBuilder 方法: 优化后的 CreateSlimBuilder 方法记录了更快的平均执行时间为 1604.4 us,比 CreateBuilder 方法快约 40%。它还分配了更少的内存,约为 428.34 KB。这种性能提升可归因于减少了默认服务和配置的数量,这与该方法旨在提供更简化的启动过程的设计保持一致。

  • CreateEmptyBuilder 方法: 最简化的方法 CreateEmptyBuilder 展示了最快的平均执行时间为 121.3 us,明显快于其他两种方法。它还具有最低的内存占用,仅分配了 107.78 KB 左右。这突出了该方法的精简初始化策略,只包括显式定义的服务和配置。

标准差表明了多次运行中执行时间的可变性,其中 CreateBuilder 具有最高的可变性。这可能是由于要加载和配置的组件较多,这可能会导致初始化时间出现更多波动。

这些性能测试表明 CreateSlimBuilder,CreateEmptyBuilder 与传统 CreateBuilder 方法相比,它们具有显著的性能优势。当性能是关键因素时,开发人员应该考虑这些选项,特别是在启动时间和内存效率至关重要的环境中。

但需要注意的是,这些性能改进是以功能为代价的。虽然CreateEmptyBuilder提供了最快的启动速度和最低的资源消耗,但它要求开发人员手动配置所有必需的服务,这可能会增加开发的复杂性和时间。CreateSlimBuilder提供了一个折衷方案,提供了一些默认配置,同时仍允许更精简的应用程序设置。

结论

在 .NET 8 中,Builder 方法的选择不仅仅是一个技术决策,而是一个受项目独特需求影响的战略决策。性能测试为这一选择提供了量化基础,确保开发人员能够做出符合他们性能目标和开发理念的决策。

有关更多资料,请参阅 Microsoft Docs. (2023). “ASP.NET Core 8.0 release notes., https://learn.microsoft.com/en-us/aspnet/core/fundamentals/native-aot?view=aspnetcore-8.0,The 2 New Web Application Types Added in .NET 8

与[翻译].NET 8 的原生AOT及高性能Web开发中的应用[附性能测试结果]相似的内容:

[翻译].NET 8 的原生AOT及高性能Web开发中的应用[附性能测试结果]

随着 .NET 8 的发布,微软迈出了重要一步,为 ASP.NET Core 引入了原生的 Ahead-of-Time (AOT) 编译。这一进步不仅提高了应用程序的性能,还简化了开发过程,标志着 .NET 生态系统进入了新的时代。

.NET周报 【3月第4期 2023-03-24】

国内文章 .NET应用系统的国际化-多语言翻译服务 https://www.cnblogs.com/tianqing/p/17232559.html 本文重点介绍了多语言翻译服务的设计和实现。文章描述了如何通过多语言翻译服务,将临时存储在数据库中的多语言词条,按支持的语言翻译成多语言词条。作者设计了

.NET 7 中 LINQ 的疯狂性能提升

LINQ 是 Language INtegrated Query 单词的首字母缩写,翻译过来是语言集成查询。它为查询跨各种数据源和格式的数据提供了一致的模型,所以叫集成查询。由于这种查询并没有制造新的语言而只是在现有的语言基础上来实现,所以叫语言集成查询。语言集成查询 (LINQ) 是一系列直接将查

【ASP.NET Core】标记帮助器——抽象层

标记帮助器,即 Tag Helpers。这个嘛,就直接翻译了,叫“标记帮助器”,虽然不好听,但只能这样了。当然你翻译为“标记增强器”也行。 所谓标记帮助器,就是针对 HTML 标签(不管是标准的还是自己命名的)进行扩展的做法。它是以 Razor 为基础的,服务于开发人员的。在服务器端用 C# 代码来

基于EF Core存储的国际化服务

前言 .NET 官方有一个用来管理国际化资源的扩展包Microsoft.Extensions.Localization,ASP.NET Core也用这个来实现国际化功能。但是这个包的翻译数据是使用resx资源文件来管理的,这就意味着无法动态管理。虽然官方有在文档中提供了一些第三方管理方案,但是都不太

[转帖]eBPF文章翻译(2)——BCC介绍(附实验环境)

nevermosby eBPF学习计划可以看这里。 该篇为入门文章翻译系列第二篇,第一篇看这里。 原文名称:An introduction to the BPF Compiler Collection,原文地址:https://lwn.net/Articles/742082/ 目录 BCC是什么 一

动手学Avalonia:基于SemanticKernel与硅基流动构建AI聊天与翻译工具

Avalonia是什么? Avalonia是一个跨平台的UI框架,专为.NET开发打造,提供灵活的样式系统,支持Windows、macOS、Linux、iOS、Android及WebAssembly等多种平台。它已成熟并适合生产环境,被Schneider Electric、Unity、JetBrai

[转帖]一个小操作,SQL 查询速度翻了 1000 倍

https://tidb.net/book/tidb-monthly/2022/2022-04/usercase/sql-1000 背景介绍​ 某一天早上来到公司,接到业务同学反馈,线上某个SQL之前查询速度很快,从某个时间点开始查询速度突然变慢了,希望DBA帮忙查看下。业务同学反馈的原话如下: ​

validator库在gin中的使用

目录封装语言包翻译器tag中设置验证规则控制层验curl请求返回结果 封装语言包翻译器 package validator import ( "fmt" "net/http" "reflect" "github.com/go-playground/locales/zh_Hans_CN" unTran

[转帖]兄弟们,时代变了

https://my.oschina.net/mengshuai/blog/615333 献给默默无闻,奋斗在第一线的苦逼程序员们! 起因 无意间翻看了之前在 Evernote 的关于服务器端记录的开发笔记,感触良多。 2009-2010 的上面记录的大多都是关于 Nginx、Apache、MySQ