.NET8.0 AOT 经验分享 - 专项测试各大 ORM 是否支持

AOT 特点

发布和部署本机 AOT 应用具有以下优势:

  • 最大程度减少磁盘占用空间:使用本机 AOT 发布时,将生成一个可执行文件,其中仅包含支持程序所需的外部依赖项的代码。减小的可执行文件大小可能会导致:较小的容器映像,例如在容器化部署方案中。缩短了较小映像的部署时间。

  • 缩短启动时间:本机 AOT 应用程序可缩短启动时间,这意味着应用已准备好更快地为请求提供服务。改进了容器业务流程协调程序需要管理从应用的一个版本到另一个版本的转换的部署。

  • 减少内存需求:本机 AOT 应用可能会减少内存需求,具体由应用执行的工作决定。 减少内存消耗可以提高部署密度和可伸缩性。

模板应用在基准测试实验室中运行,来比较 AOT 已发布的应用、已修剪的运行时应用和未修剪的运行时应用的性能。下图显示了基准测试的结果:


本文内容

2023年11月15日,对.net的开发圈是一个重大的日子,.net 8.0正式版发布。

那一天,我发表了一篇关于 《.NET8.0 的升级和 AOT 经验的文章》,整体总结如下:

.NET8.0 AOT 已经到了可用的阶段,期待未来版本能改进以下问题:

  • 发布速度变快,目前20-30秒一次实在太慢

  • 编译前检查错误,而不是等发布后再报运行时错误

  • 加强调试,.pdb 100兆++ 为何调试还都是 c++ 有关内容,不能白瞎了这么大的调试文件啊

  • 尽快修复 Console.WriteLine(Enum.GetValues(typeof(TaskInterval))) 这个问题

如果一个全新的 AOT webapi 应用发布在国产系统上运行,算不算国产信创?

我是开源人:2881099 · GitHub

今天发表 AOT 经验的续篇和 ORM 有关,肯定会产生一些火药味,咱们能不能理智用技术的角度看完内容,提示:测试你不是贬低你,OK???

我在 github 上创建一个专门测试 AOT 发布的开源项目,有兴趣可以参与提交代码。

GitHub - 2881099/aot_test: 测试 AOT 发布


FreeSql v3.2.805 + Sqlite

复制代码
发布耗时 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】测试结束.

PS:没有对 AOT 的支持做专门改进,都是老代码。


SqlSugar v5.1.4.117 + Sqlite

程序代码设置要求:

复制代码
StaticConfig.EnableAot = true;

发布耗时 01:51.002 分钟

orm_sqlsugar.exe                 ( 50,133KB)
orm_sqlsugar.pdb                 (346,412KB)
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】开始测试...
Insert 1条 214ms
Select 1条 29ms
Update 1条 119ms
Select 1条 0ms
Delete 1条 82ms
【SqlSugar AOT】测试结束.

EFCore v8.0 + Sqlite

复制代码
发布耗时 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 已经出了新的 DapperAOT 版本,就不测试了,100%支持 AOT。

写到最后

希望多用技术交流,我写文章不是自夸 Free 系列开源项目有多流弊,实实在在的花了时间研究,测试通过后才发的文章,分享给大家多一个选择,让大家知晓已支持 AOT,仅此而已。

提示:测试你不是贬低你,OK???其他 ORM 可以按 GitHub - 2881099/aot_test: 测试 AOT 发布 的方式提交测试代码,我确实没时间测试所有 ORM,不是为了比较而比较。

被抢 SEO 关键字行为已经不是一次两次了,确实没多大意思。

最后上一个统计表格吧,PS:支持 AOT 没什么了不起!

原文链接:https://www.cnblogs.com/FreeSql/p/17842391.html

相关推荐
喜欢踢足球的老罗7 分钟前
一张跨域图的“四次换乘“:blob URL 与 Chrome 扩展架构里的工程艺术
前端·chrome·架构
程序员黑豆8 分钟前
AI全栈开发 - Java:基本数据类型 vs 引用数据类型的内存存储
java·前端·ai编程
FserSuN9 分钟前
Chrome CORS / PNA / LNA 问题排查与解决方案
前端·chrome
小小小小宇17 分钟前
Claude Code 自动运行方法大全
前端
道友可好18 分钟前
AI 测试全绿,代码却是错的
前端·人工智能·后端
techdashen36 分钟前
Rust 基础设施团队 2025 Q4 回顾与 2026 Q1 计划
开发语言·后端·rust
国科安芯38 分钟前
商业航天通信载荷数字处理单元供电架构研究——基于ASP7A84AS的高精度低压差线性稳压器技术分析
前端·单片机·嵌入式硬件·fpga开发·架构·安全性测试
神奇小汤圆1 小时前
互联网大厂精选面试八股文(附2026最新Java+AI高频题)| 建议收藏
后端
春天花会开1311 小时前
影像上传前置机网络架构设计模板(含VPN)
后端·架构