.NET8.0 AOT 经验分享 - 专项测试各大 ORM 是否支持
AOT 特點
發(fā)布和部署本機(jī) AOT 應(yīng)用具有以下優(yōu)勢:
- 最大程度減少磁盤占用空間:使用本機(jī) AOT 發(fā)布時,將生成一個可執(zhí)行文件,其中僅包含支持程序所需的外部依賴項的代碼。減小的可執(zhí)行文件大小可能會導(dǎo)致:
- 較小的容器映像,例如在容器化部署方案中。
- 縮短了較小映像的部署時間。
- 縮短啟動時間:本機(jī) AOT 應(yīng)用程序可縮短啟動時間,這意味著
- 應(yīng)用已準(zhǔn)備好更快地為請求提供服務(wù)。
- 改進(jìn)了容器業(yè)務(wù)流程協(xié)調(diào)程序需要管理從應(yīng)用的一個版本到另一個版本的轉(zhuǎn)換的部署。
- 減少內(nèi)存需求:本機(jī) AOT 應(yīng)用可能會減少內(nèi)存需求,具體由應(yīng)用執(zhí)行的工作決定。 減少內(nèi)存消耗可以提高部署密度和可伸縮性。
模板應(yīng)用在基準(zhǔn)測試實驗室中運(yùn)行,來比較 AOT 已發(fā)布的應(yīng)用、已修剪的運(yùn)行時應(yīng)用和未修剪的運(yùn)行時應(yīng)用的性能。下圖顯示了基準(zhǔn)測試的結(jié)果:
本文內(nèi)容
2023年11月15日,對.net的開發(fā)圈是一個重大的日子,.net 8.0正式版發(fā)布。
那一天,我發(fā)表了一篇關(guān)于 《.NET8.0 的升級和 AOT 經(jīng)驗的文章》,整體總結(jié)如下:
.NET8.0 AOT 已經(jīng)到了可用的階段,期待未來版本能改進(jìn)以下問題:
- 發(fā)布速度變快,目前20-30秒一次實在太慢
- 編譯前檢查錯誤,而不是等發(fā)布后再報運(yùn)行時錯誤
- 加強(qiáng)調(diào)試,.pdb 100兆++ 為何調(diào)試還都是 c++ 有關(guān)內(nèi)容,不能白瞎了這么大的調(diào)試文件啊
- 盡快修復(fù) Console.WriteLine(Enum.GetValues(typeof(TaskInterval))) 這個問題
如果一個全新的 AOT webapi 應(yīng)用發(fā)布在國產(chǎn)系統(tǒng)上運(yùn)行,算不算國產(chǎn)信創(chuàng)?
我是開源人:https://github.com/2881099
今天發(fā)表 AOT 經(jīng)驗的續(xù)篇和 ORM 有關(guān),肯定會產(chǎn)生一些火藥味,咱們能不能理智用技術(shù)的角度看完內(nèi)容,提示:測試你不是貶低你,OK???
我在 github 上創(chuàng)建一個專門測試 AOT 發(fā)布的開源項目,有興趣可以參與提交代碼。
https://github.com/2881099/aot_test
FreeSql v3.2.805 + Sqlite
發(fā)布耗時 31.882 秒
orm_freesql.exe ( 16,927KB)
orm_freesql.pdb (123,812KB)
SQLite.Interop.dll ( 1,723KB)
E:\github\aot_test\orm_freesql\bin\Release\net8.0\publish\win-x64>orm_freesql.exe
【FreeSql AOT】開始測試...
Insert 1條 80ms
Select 1條 5ms
Update 1條 86ms
Select 1條 0ms
Delete 1條 74ms
【FreeSql AOT】測試結(jié)束.
PS:沒有對 AOT 的支持做專門改進(jìn),都是老代碼。
SqlSugar v5.1.4.117 + Sqlite
發(fā)布耗時 01:22.813 分鐘
orm_sqlsugar.exe ( 39,875KB)
orm_sqlsugar.pdb (266,084KB)
e_sqlite3 ( 1,597KB)
Microsoft.Data.SqlClient.SNI.dll ( 499KB)
E:\github\aot_test\orm_sqlsugar\bin\Release\net8.0\publish\win-x64>orm_sqlsugar.exe
【SqlSugar AOT】開始測試...
Unhandled Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'type')
at System.ArgumentNullException.Throw(String) + 0x2b
at System.ActivatorImplementation.CreateInstance(Type, Boolean) + 0xe7
at SqlSugar.InstanceFactory.NoCacheGetCacheInstance[T](String) + 0x84
at SqlSugar.InstanceFactory.CreateInstance[T](String) + 0x82
at SqlSugar.InstanceFactory.GetCodeFirst(ConnectionConfig) + 0x3e
at SqlSugar.SqlSugarProvider.get_CodeFirst() + 0x1a
at Program.<Main>$(String[] args) + 0x138
at orm_sqlsugar!<BaseAddress>+0x11f25d3
上述由 .CodeFirst.InitTables<TaskInfo>() 報錯,去掉該代碼手工創(chuàng)建表之后,再次發(fā)布運(yùn)行:
發(fā)布耗時 59.911 秒
E:\github\aot_test\orm_sqlsugar\bin\Release\net8.0\publish\win-x64>orm_sqlsugar.exe
【SqlSugar AOT】開始測試...
Unhandled Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'type')
at System.ArgumentNullException.Throw(String) + 0x2b
at System.ActivatorImplementation.CreateInstance(Type, Boolean) + 0xe7
at SqlSugar.InstanceFactory.NoCacheGetCacheInstance[T](String) + 0x84
at SqlSugar.InstanceFactory.CreateInstance[T](String) + 0x82
at SqlSugar.InstanceFactory.GetSqlbuilder(ConnectionConfig) + 0x7a
at SqlSugar.SqlSugarProvider.CreateInsertable[T](T[]) + 0x39
at SqlSugar.SqlSugarProvider.Insertable[T](T[] insertObjs) + 0x3b
at SqlSugar.SqlSugarProvider.Insertable[T](List`1 insertObjs) + 0xb5
at SqlSugar.SqlSugarClient.Insertable[T](List`1) + 0x44
at Program.<Main>$(String[] args) + 0x1af
at orm_sqlsugar!<BaseAddress>+0x11f24f3
這次由 .Insertable 報錯,無解?后面還是更難兼容的更新、查詢操作沒執(zhí)行~~
https://www.cnblogs.com/sunkaixuan/p/17839825.html
《NET8 ORM 使用AOT SqlSugar posted》 @ 2023-11-17 22:31 果糖大數(shù)據(jù)科技
這篇文章是是針對 FreeSql 2023-11-16 發(fā)的 AOT 文章發(fā)的么?
https://www.cnblogs.com/FreeSql/p/17836000.html
《.NET8.0 AOT 經(jīng)驗分享 FreeSql/FreeRedis/FreeScheduler 均已通過測試》 posted @ 2023-11-16 14:18 FreeSql
FreeSql 一年沒發(fā)文章了,發(fā)一次就被針對 seo 關(guān)鍵字,好歹先測試下再發(fā)文章啊!~~
EFCore v8.0 + Sqlite
發(fā)布耗時 50.749 秒
orm_efcore.exe ( 17,410KB)
orm_efcore.pdb (168,788KB)
e_sqlite3 ( 1,652KB)
E:\github\aot_test\orm_efcore\bin\Release\net8.0\publish\win-x64>orm_efcore.exe
【EFCore AOT】開始測試...
Unhandled Exception: System.InvalidOperationException: Model building is not supported when publishing with NativeAOT. Use a compiled model.
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(Boolean) + 0x148
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() + 0x1c
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite, ServiceProviderEngineScope) + 0x3d
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier, ServiceProviderEngineScope) + 0xa3
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type) + 0x42
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider, Type) + 0x50
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider) + 0x29
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() + 0x32
at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices() + 0x14f
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() + 0x22
at Microsoft.EntityFrameworkCore.DbContext.EntryWithoutDetectChanges[TEntity](TEntity entity) + 0x18
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState) + 0x1d
at Program.<Main>$(String[] args) + 0x1da
at orm_efcore!<BaseAddress>+0x7c2ab0
Dapper
Dapper 已經(jīng)出了新的 DapperAOT 版本,就不測試了,100%支持 AOT。
寫到最后
希望多用技術(shù)交流,我寫文章不是自夸 Free 系列開源項目有多流弊,實實在在的花了時間研究,測試通過后才發(fā)的文章,分享給大家多一個選擇,讓大家知曉已支持 AOT,僅此而已。
提示:測試你不是貶低你,OK???其他 ORM 可以按 https://github.com/2881099/aot_test 的方式提交測試代碼,我確實沒時間測試所有 ORM,不是為了比較而比較。
被搶 SEO 關(guān)鍵字行為已經(jīng)不是一次兩次了,確實沒多大意思。
最后上一個統(tǒng)計表格吧,PS:支持 AOT 沒什么了不起!
| 測試項目 | 發(fā)布耗時 | 發(fā)布后 .exe 體積 | 發(fā)布后 .pdb 體積 | 通過AOT |
|---|---|---|---|---|
| FreeSql v3.2.805 + Sqlite | 31.882 秒 | 16,927KB | 123,812KB | 通過 |
| SqlSugar v5.1.4.117 + Sqlite | 82.813 秒 | 39,875KB | 266,084KB | 未通過 |
| EFCore v8.0 + Sqlite | 50.749 | 17,410KB | 168,788KB | 未通過 |
| DapperAOT | 未測試(支持) | 未測試(支持) | 未測試(支持) | 通過 |
如果大家對 AOT 有興趣,我后面會持續(xù)分享自己的經(jīng)驗,PS mysql 測試也是沒問題的,其他數(shù)據(jù)庫如果有使用問題可以與我交流。
我是開源人:https://github.com/2881099
總結(jié)
以上是生活随笔為你收集整理的.NET8.0 AOT 经验分享 - 专项测试各大 ORM 是否支持的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DX后台截图C++实现代码
- 下一篇: JavaSE面试题01:自增变量