.Net native aot簡單體驗(一)

.net native aot可以在發佈時將 IL 代碼編譯爲本地代碼,從而提高應用程序的性能和效的發佈方式,其主要優點有:

  • 縮小磁盤佔用
  • 降低啓動時間
  • 減少內存需求

如果用於個人發佈的小程序來說,還有如下兩個優點:

  • 不用安裝
  • 防止反編譯

雖然.net 7就已經支持native aot了,但只能用於控制檯程序,使用場景有很大的限制,並沒有怎麼研究它。最近裝了.net 8 preview版,發現是支持asp.net的aot的,便找了個時間簡單的體驗下aot。

前置條件

由於NativeAOT需要c++編譯器將其變成native程序,因此除了.net core sdk外,還需要安裝C++編譯器, 在Windows下微軟提供的方案是安裝 "Desktop development with C++"的工作負載。

這還還需要附帶安裝一個VisualStudio,算是一個比較重的安裝了。根據微軟的文章,目前沒有提供不安裝VisualStudio的方案的計劃。

參考文章:Tutorial: Publish an ASP.NET Core app using native AOT。

 

簡單示例

以一個簡單的控制檯程序爲例:

Console.WriteLine("Hello, World!");

要添加aot發佈選項,有兩個方法:

1. 在csproj項目文件中添加PublishAot選項
<PropertyGroup>
    <PublishAot>true</PublishAot>
</PropertyGroup>

這樣,通過dotnet publish發佈的時候,會自動將其發佈成native aot的程序

但需要注意的是,放在csproj的時候,會對ide造成一定的影響,會導致在ide中進行aot,這並不是我們所需要的,此時需要加條件參數 Condition=" '$(Configuration)' == 'Release' "

另外,默認是會生成pdb文件的,對於native程序,很多時候這個pdb文件會非常大,如果我們發佈的時候想去掉它,可以添加如下選項。

        <DebugType>none</DebugType>
        <DebugSymbols>false</DebugSymbols>
2. 在命令行中添加參數/p:PublishAot=true,完整命令如下:

dotnet publish /p:PublishAot=true

這兩種方式本質是一樣的,實際上,在PropertyGroup中的所有參數都可以通過/p的方式動態添加。在命令行中更靈活,具體看怎麼使用看需求了。

打包後,由於這個程序非常簡單,直接成功了,我使用的是.net 8 preview的版本,最終的發佈包只有1.4m。看來.net 8對native aot有了進一步的優化。

 

WinForm程序AOT

目前.net 8還不支持對winform的aot,aot的時候會出現如下錯誤:Error NETSDK1175 : 啓用剪裁時,不支持或不推薦使用 Windows 窗體

不過這個錯誤可以通過_SuppressWinFormsTrimError參數屏蔽掉

<PropertyGroup>
    <PublishAot>true</PublishAot>
    <_SuppressWinFormsTrimError>true</_SuppressWinFormsTrimError>
</PropertyGroup>

屏蔽掉後,可以順利生產Native的程序,也能正常的啓動和執行。不過編譯過程中伴隨着一大堆的告警,如果用這種方式發佈文件還是需要好好測試的。

和控制檯程序比起來,由於WinForm包含了UI庫,其輸出程序要大得多,達到了54mb(.net 7的aot程序是32mb,估計.net 8的winform aot還有進一步優化的空間)。雖然對比100mb+的自包含模式要校不少,但如果是小程序這個體積還是有點難以接受的。

用7z壓縮了下,大小是13mb,壓縮後的大小還是可以接受的。我便嘗試了用upx壓縮了一下:

./upx --best WinFormsApp1.exe

File size Ratio Format Name
-------------------- ------ ----------- -----------
57275904 -> 17455616 30.48% win64/pe WinFormsApp1.exe

帶ui的winform程序直接被壓縮到了16m,體積基本上接近7z的壓縮包了,不過第一次啓動速度慢不少,內存佔用暴漲。 後續的小程序都可以考慮用這種方式發佈了,不用安裝運行時直接啓動還是非常有吸引力的。

WPF程序AOT

WPF程序和WinForm一樣不支持aot,會報錯不支持,雖然有參數_SuppressWPFTrimError可以使用,但是編譯後的程序無法啓動。由於WPF程序使用了大量反射,支持aot天生有難度,估計短期是不用指望了。

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章