當前位置: 妍妍網 > 碼農

.NET 8 原生AOT高效能Web開發:實戰與效能測試

2024-06-24碼農

前言

隨著 .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;
    namespaceNewAppTypes
    {
    [MemoryDiagnoser]
    public classBenchMarks
    {
    publicstring[]? Args { getprivateset; }
    [Benchmark]
    publicvoidCreateBuilder()
    {
    var builder = WebApplication.CreateBuilder(Args);
    var app = builder.Build();
    builder.WebHost.UseUrls("http://*:80", "https://*.443");

    app.MapGet("/", () => "Hello World!");
    }
    [Benchmark]
    publicvoidCreateSlimBuilder()
    {
    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]
    publicvoidCreateEmptyBuilder()
    {
    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 方法的選擇不僅僅是一個技術決策,而是一個受計畫獨特需求影響的戰略決策。效能測試為這一選擇提供了量化基礎,確保開發人員能夠做出符合他們效能目標和開發理念的決策。

    轉自:Rwing

    連結:cnblogs.com/Rwing/p/18262526/

    a-dive-into-net-8-native-aot-and-efficient-web-development

    - EOF -

    推薦閱讀 點選標題可跳轉

    看完本文有收獲?請轉發分享給更多人

    推薦關註「DotNet」,提升.Net技能

    點贊和在看就是最大的支持❤️