.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 应用发布在国产系统上运行,算不算国产信创?
我是开源人:https://github.com/2881099
今天发表 AOT 经验的续篇和 ORM 有关,肯定会产生一些火药味,咱们能不能理智用技术的角度看完内容,提示:测试你不是贬低你,OK???
我在 github 上创建一个专门测试 AOT 发布的开源项目,有兴趣可以参与提交代码。
https://github.com/2881099/aot_test
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
发布耗时 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>() 报错,去掉该代码手工创建表之后,再次发布运行:
发布耗时 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 报错,无解?后面还是更难兼容的更新、查询操作没执行~~
https://www.cnblogs.com/sunkaixuan/p/17839825.html
《NET8 ORM 使用AOT SqlSugar posted》 @ 2023-11-17 22:31 果糖大数据科技
这篇文章是是针对 FreeSql 2023-11-16 发的 AOT 文章发的么?
https://www.cnblogs.com/FreeSql/p/17836000.html
《.NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试》 posted @ 2023-11-16 14:18 FreeSql
FreeSql 一年没发文章了,发一次就被针对 seo 关键字,好歹先测试下再发文章啊!~~
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 可以按 https://github.com/2881099/aot_test 的方式提交测试代码,我确实没时间测试所有 ORM,不是为了比较而比较。
被抢 SEO 关键字行为已经不是一次两次了,确实没多大意思。
最后上一个统计表格吧,PS:支持 AOT 没什么了不起!
| 测试项目 | 发布耗时 | 发布后 .exe 体积 | 发布后 .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 有兴趣,我后面会持续分享自己的经验,PS mysql 测试也是没问题的,其他数据库如果有使用问题可以与我交流。
我是开源人:https://github.com/2881099
.NET8.0 AOT 经验分享 - 专项测试各大 ORM 是否支持的更多相关文章
- 一次压力测试Loadrunner经验分享
一次压力测试Loadrunner经验分享 http://blog.csdn.net/lxlmj/article/category/553431 loadrunner测试socketstcpserver ...
- Selenium执行测试脚本稳定性的一些经验分享交流
Selenium执行测试脚本稳定性的一些经验分享交流 公司的自动化WEB测试框架IATA已上线运行了一段时间,期间发现一些脚本稳定性的问题,与大家分享一下. CASE执行游览器:ie firefox ...
- 【原创经验分享】JQuery(Ajax)调用WCF服务
最近在学习这个WCF,由于刚开始学 不久,发现网上的一些WCF教程都比较简单,感觉功能跟WebService没什么特别大的区别,但是看网上的介绍,就说WCF比WebService牛逼多少多少,反正我刚 ...
- (转)CMOS Sensor的调试经验分享
CMOS Sensor的调试经验分享 我这里要介绍的就是CMOS摄像头的一些调试经验. 首先,要认识CMOS摄像头的结构.我们通常拿到的是集成封装好的模组,一般由三个部分组成:镜头.感应器和图像信号处 ...
- 关于启用 HTTPS 的一些经验分享(二)
转载: 关于启用 HTTPS 的一些经验分享(二) 几天前,一位朋友问我:都说推荐用 Qualys SSL Labs 这个工具测试 SSL 安全性,为什么有些安全实力很强的大厂家评分也很低?我认为这个 ...
- 线上Linux服务器运维安全策略经验分享
线上Linux服务器运维安全策略经验分享 https://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=402022683&idx=1&a ...
- CMOS Sensor的调试经验分享
转自:http://bbs.52rd.com/forum.php?mod=viewthread&tid=276351 CMOS Sensor的调试经验分享 我这里要介绍的就是CMOS摄像头的一 ...
- 关于Java解压文件的一些坑及经验分享(MALFORMED异常)
文章也已经同步到我的csdn博客: http://blog.csdn.net/u012881584/article/details/72615481 关于Java解压文件的一些坑及经验分享 就在本周, ...
- 【老司机经验】CC2530&STM8S105二合一嵌入式学习板设计思路与经验分享
CC2530&STM8S105二合一嵌入式学习板设计思路与经验分享 1.缘起 这些年来一直在其他公司的实验箱和别人的开发板上进行教学与开发工作,总是觉得功能设计不那么合意.心里突然冒出个 ...
- 沉淀,再出发——在Ubuntu Kylin15.04中配置Hadoop单机/伪分布式系统经验分享
在Ubuntu Kylin15.04中配置Hadoop单机/伪分布式系统经验分享 一.工作准备 首先,明确工作的重心,在Ubuntu Kylin15.04中配置Hadoop集群,这里我是用的双系统中的 ...
随机推荐
- 王道oj/problem17
网址:http:oj.lgwenda.com/problem17 思路:指针其实就是存储地址的一个空间,LinkList=LNode* 代码: #define _CRT_SECURE_NO_WARNI ...
- .NET技术:懒惰与沉淀的平衡之道
在过去的很多年里,我一直默默搬砖,而我们聚在博客园,目的只有一个:沉淀并为更多的.NET开发者提供更好的帮助. 疫情3年,个人经历了太多事情,感觉懒惰是最大的敌人.然而,在这里,我收获了许多宝贵的经验 ...
- 从零玩转系列之微信支付实战PC端支付微信取消接口搭建 | 技术创作特训营第一期
一.前言 从零玩转系列之微信支付实战PC端支付微信取消接口搭建 | 技术创作特训营第一期 halo各位大佬很久没更新了最近在搞微信支付,因商户号审核了我半个月和小程序认证也找了资料并且将商户号和小程序 ...
- 终于搞懂了python2和python3的encode(编码)与decode(解码)
终于搞懂了python2的编码 在python2下碰到非常多次的中文乱码,这次来梳理一下编码问题. 在python 2中默认编码是 ASCII,而在python 3中默认编码是 unicode. un ...
- CI+JUnit5并发单测机制创新实践
一. 现状·问题 针对现如今高并发场景的业务系统,"并发问题" 终归是必不可少的一类(占比接近10%),每次出现问题和事故后,需要耗费大量人力成本排查分析并修复.那如果能在事前尽可 ...
- SSM登录操作
1.编写实体类 略 2. 写mapper映射文件 通过名字查询 通过ID主键查询... 略 写dao CRUD相关抽象方法 List<Student> getAll(); Student ...
- Hugging News #0821: Hugging Face 完成 2.35 亿美元 D 轮融资
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- WPF学习 - 用鼠标移动、缩放、旋转图片(1)
1. 需求 其实我的需求很简单.就是想做一个图片查看器,可以通过鼠标来平移.缩放.旋转图片. 2. 解决思路: WPF中的UIElement提供了RenderTransform属性,用于承载各种Tra ...
- 白盒AES和SM4实现的差分故障分析
DFA攻击背景介绍 传统的密码安全性分析环境被称为黑盒攻击环境,攻击者只能访问密码系统的输入与输出,但随着密码系统部署环境的多样化,该分析模型已经不能够反映实际应用中攻击者的能力.2002年,Chow ...
- MapReduce核心概念及架构
MapReduce简介 MapReduce常用于对大规模数据集(大于1TB)的并行运算,或对大数据进行加工.挖掘和优化等处理. MapReduce将并行计算过程高度抽象到了两个函数map和reduce ...