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

  1. 发布耗时 31.882
  2. orm_freesql.exe ( 16,927KB)
  3. orm_freesql.pdb (123,812KB)
  4. SQLite.Interop.dll ( 1,723KB)
  5. E:\github\aot_test\orm_freesql\bin\Release\net8.0\publish\win-x64>orm_freesql.exe
  6. FreeSql AOT】开始测试...
  7. Insert 1 80ms
  8. Select 1 5ms
  9. Update 1 86ms
  10. Select 1 0ms
  11. Delete 1 74ms
  12. FreeSql AOT】测试结束.

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


SqlSugar v5.1.4.117 + Sqlite

  1. 发布耗时 01:22.813 分钟
  2. orm_sqlsugar.exe ( 39,875KB)
  3. orm_sqlsugar.pdb (266,084KB)
  4. e_sqlite3 ( 1,597KB)
  5. Microsoft.Data.SqlClient.SNI.dll ( 499KB)
  6. E:\github\aot_test\orm_sqlsugar\bin\Release\net8.0\publish\win-x64>orm_sqlsugar.exe
  7. SqlSugar AOT】开始测试...
  8. Unhandled Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'type')
  9. at System.ArgumentNullException.Throw(String) + 0x2b
  10. at System.ActivatorImplementation.CreateInstance(Type, Boolean) + 0xe7
  11. at SqlSugar.InstanceFactory.NoCacheGetCacheInstance[T](String) + 0x84
  12. at SqlSugar.InstanceFactory.CreateInstance[T](String) + 0x82
  13. at SqlSugar.InstanceFactory.GetCodeFirst(ConnectionConfig) + 0x3e
  14. at SqlSugar.SqlSugarProvider.get_CodeFirst() + 0x1a
  15. at Program.<Main>$(String[] args) + 0x138
  16. at orm_sqlsugar!<BaseAddress>+0x11f25d3

上述由 .CodeFirst.InitTables<TaskInfo>() 报错,去掉该代码手工创建表之后,再次发布运行:

  1. 发布耗时 59.911
  2. E:\github\aot_test\orm_sqlsugar\bin\Release\net8.0\publish\win-x64>orm_sqlsugar.exe
  3. SqlSugar AOT】开始测试...
  4. Unhandled Exception: System.ArgumentNullException: Value cannot be null. (Parameter 'type')
  5. at System.ArgumentNullException.Throw(String) + 0x2b
  6. at System.ActivatorImplementation.CreateInstance(Type, Boolean) + 0xe7
  7. at SqlSugar.InstanceFactory.NoCacheGetCacheInstance[T](String) + 0x84
  8. at SqlSugar.InstanceFactory.CreateInstance[T](String) + 0x82
  9. at SqlSugar.InstanceFactory.GetSqlbuilder(ConnectionConfig) + 0x7a
  10. at SqlSugar.SqlSugarProvider.CreateInsertable[T](T[]) + 0x39
  11. at SqlSugar.SqlSugarProvider.Insertable[T](T[] insertObjs) + 0x3b
  12. at SqlSugar.SqlSugarProvider.Insertable[T](List`1 insertObjs) + 0xb5
  13. at SqlSugar.SqlSugarClient.Insertable[T](List`1) + 0x44
  14. at Program.<Main>$(String[] args) + 0x1af
  15. 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

  1. 发布耗时 50.749
  2. orm_efcore.exe ( 17,410KB)
  3. orm_efcore.pdb (168,788KB)
  4. e_sqlite3 ( 1,652KB)
  5. E:\github\aot_test\orm_efcore\bin\Release\net8.0\publish\win-x64>orm_efcore.exe
  6. EFCore AOT】开始测试...
  7. Unhandled Exception: System.InvalidOperationException: Model building is not supported when publishing with NativeAOT. Use a compiled model.
  8. at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(Boolean) + 0x148
  9. at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() + 0x1c
  10. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
  11. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
  12. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
  13. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
  14. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
  15. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
  16. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
  17. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
  18. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
  19. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
  20. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
  21. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
  22. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
  23. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
  24. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
  25. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
  26. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
  27. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
  28. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
  29. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite, RuntimeResolverContext) + 0x83
  30. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite, RuntimeResolverContext, ServiceProviderEngineScope, RuntimeResolverLock) + 0xc2
  31. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite, RuntimeResolverContext) + 0x35
  32. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument) + 0xa4
  33. at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite, ServiceProviderEngineScope) + 0x3d
  34. at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier, ServiceProviderEngineScope) + 0xa3
  35. at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type) + 0x42
  36. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider, Type) + 0x50
  37. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider) + 0x29
  38. at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() + 0x32
  39. at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices() + 0x14f
  40. at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() + 0x22
  41. at Microsoft.EntityFrameworkCore.DbContext.EntryWithoutDetectChanges[TEntity](TEntity entity) + 0x18
  42. at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState) + 0x1d
  43. at Program.<Main>$(String[] args) + 0x1da
  44. 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 是否支持的更多相关文章

  1. 一次压力测试Loadrunner经验分享

    一次压力测试Loadrunner经验分享 http://blog.csdn.net/lxlmj/article/category/553431 loadrunner测试socketstcpserver ...

  2. Selenium执行测试脚本稳定性的一些经验分享交流

    Selenium执行测试脚本稳定性的一些经验分享交流 公司的自动化WEB测试框架IATA已上线运行了一段时间,期间发现一些脚本稳定性的问题,与大家分享一下. CASE执行游览器:ie firefox ...

  3. 【原创经验分享】JQuery(Ajax)调用WCF服务

    最近在学习这个WCF,由于刚开始学 不久,发现网上的一些WCF教程都比较简单,感觉功能跟WebService没什么特别大的区别,但是看网上的介绍,就说WCF比WebService牛逼多少多少,反正我刚 ...

  4. (转)CMOS Sensor的调试经验分享

    CMOS Sensor的调试经验分享 我这里要介绍的就是CMOS摄像头的一些调试经验. 首先,要认识CMOS摄像头的结构.我们通常拿到的是集成封装好的模组,一般由三个部分组成:镜头.感应器和图像信号处 ...

  5. 关于启用 HTTPS 的一些经验分享(二)

    转载: 关于启用 HTTPS 的一些经验分享(二) 几天前,一位朋友问我:都说推荐用 Qualys SSL Labs 这个工具测试 SSL 安全性,为什么有些安全实力很强的大厂家评分也很低?我认为这个 ...

  6. 线上Linux服务器运维安全策略经验分享

    线上Linux服务器运维安全策略经验分享 https://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=402022683&idx=1&a ...

  7. CMOS Sensor的调试经验分享

    转自:http://bbs.52rd.com/forum.php?mod=viewthread&tid=276351 CMOS Sensor的调试经验分享 我这里要介绍的就是CMOS摄像头的一 ...

  8. 关于Java解压文件的一些坑及经验分享(MALFORMED异常)

    文章也已经同步到我的csdn博客: http://blog.csdn.net/u012881584/article/details/72615481 关于Java解压文件的一些坑及经验分享 就在本周, ...

  9. 【老司机经验】CC2530&STM8S105二合一嵌入式学习板设计思路与经验分享

    CC2530&STM8S105二合一嵌入式学习板设计思路与经验分享 1.缘起    这些年来一直在其他公司的实验箱和别人的开发板上进行教学与开发工作,总是觉得功能设计不那么合意.心里突然冒出个 ...

  10. 沉淀,再出发——在Ubuntu Kylin15.04中配置Hadoop单机/伪分布式系统经验分享

    在Ubuntu Kylin15.04中配置Hadoop单机/伪分布式系统经验分享 一.工作准备 首先,明确工作的重心,在Ubuntu Kylin15.04中配置Hadoop集群,这里我是用的双系统中的 ...

随机推荐

  1. AttributeError: 'EmailUse' object has no attribute 'SendMail'

    错误原因:函数名与模块名重复 解决方案:不要将函数名与模块名重复

  2. 你真的知道吗?catch、finally和return哪个先执行

    我的一位朋友前阵子遇到一个问题,问题的核心就是try--catch--finally中catch和finally代码块到底哪个先执.这个问题看起来很简单,当然是"catch先执行.final ...

  3. VMware中的三种网络模式

    1.桥接模式网络 通过桥接模式网络连接,虚拟机中的虚拟网络适配器可连接到主机中的物理网络适配器.虚拟机可通过主机网络适配器连接到主机系统所用的 LAN.桥接模式网络连接支持有线和无线主机网络适配器. ...

  4. 二代水务系统架构设计分享——DDD+个性化

    系统要求 C/S架构的单体桌面应用,可以满足客户个性化需求,易于升级和维护.相比于一代Winform,界面要求美观,控件丰富可定制. 解决方案 依托.Net6开发平台,采用模块化思想设计(即分而治之的 ...

  5. VScode软件的安装以及C/C++环境配置的方法

    今天和大家分享一下VScode软件的安装以及C/C++环境配置的方法.手把手教大家入门. 1,下载VScode编译器 (1)    官网下载链接:https://code.visualstudio.c ...

  6. 每天一道面试题:Spring的Bean生命周期

    Spring的Bean生命周期包括以下步骤: 1.实例化(Instantiation):当Spring容器接收到创建Bean的请求时,它会先实例化Bean对象.这个过程可以通过构造函数.工厂方法或者反 ...

  7. iOS日志获取

    IOS日志获取 崩溃日志存放目录: /var/mobile/Library/Logs/CrashReporter

  8. MapReduce核心概念及架构

    MapReduce简介 MapReduce常用于对大规模数据集(大于1TB)的并行运算,或对大数据进行加工.挖掘和优化等处理. MapReduce将并行计算过程高度抽象到了两个函数map和reduce ...

  9. 当开源项目 Issue 遇到了 DevChat

    目录 1. 概述 2. Bug 分析与复现 3. Bug 定位与修复 4. 代码测试 5. 文档更新 6. 提交 Commit 7. 总结 1. 概述 没错,又有人给 GoPool 项目提 issue ...

  10. 解读Redis常见命令

    Redis数据结构介绍 Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样: 贴心小建议:命令不要死记,学会查询就好啦 Redis为了方便我们学习, ...