SourceGenerator 生成db to class代码优化结果记录
优化
上一次实验 代码写的较为随意,本次穷尽所学,优化了一把,
不过果然还是没 比过 Dapper aot, 虽然没使用 Interceptor, 但理论上其优化不该有这么大差距
知识差距不少呀,都看不懂 Dapper aot 利用了什么姿势领先, 有大神们能教教吗?
优化点
减少类型判断
提前 做类型判断,并在生成时利用 switch case 减少判断
之前
var needConvert = typeof(string) != reader.GetFieldType(i);
s.Add((d,r) => d.Name = DBExtensions.ReadToString(r,j,needConvert));
之后
switch (name)
{
case "age":
s.Add(type == typeof(int) ? 1 : 2);
break;
switch (ss[j])
{
case 1:
d.Age = EntitiesGenerator.ReadToInt32Nullable(reader,j);
break;
case 2:
d.Age = EntitiesGenerator.ReadToInt32NullableConvert(reader,j);
break;
避免生成委托
去除委托生成使用
之前
var s = new List<Action<BenchmarkTest.Dog, IDataReader>>(reader.FieldCount);
for (int i = 0; i < reader.FieldCount; i++)
{
var j = i;
switch (reader.GetName(j).ToLower())
{
case "age":
{
// int?
var needConvert = typeof(int) != reader.GetFieldType(i);
s.Add((d,r) => d.Age = DBExtensions.ReadToInt32Nullable(r,j,needConvert));
}
break;
case "name":
{
// string
var needConvert = typeof(string) != reader.GetFieldType(i);
s.Add((d,r) => d.Name = DBExtensions.ReadToString(r,j,needConvert));
}
break;
case "weight":
{
// float?
var needConvert = typeof(float) != reader.GetFieldType(i);
s.Add((d,r) => d.Weight = DBExtensions.ReadToFloatNullable(r,j,needConvert));
}
break;
default:
break;
}
}
while (reader.Read())
{
var d = new BenchmarkTest.Dog();
foreach (var item in s)
{
item?.Invoke(d,reader);
}
yield return d;
}
之后
var s = new List<int>(reader.FieldCount);
for (int i = 0; i < reader.FieldCount; i++)
{
var name = reader.GetName(i).ToLower();
var type = reader.GetFieldType(i);
switch (name)
{
case "age":
s.Add(type == typeof(int) ? 1 : 2);
break;
case "name":
s.Add(type == typeof(string) ? 3 : 4);
break;
case "weight":
s.Add(type == typeof(float) ? 5 : 6);
break;
default:
break;
}
}
ss = s.ToArray();
var d = new BenchmarkTest.Dog();
for (int j = 0; j < ss.Length; j++)
{
switch (ss[j])
{
case 1:
d.Age = EntitiesGenerator.ReadToInt32Nullable(reader,j);
break;
case 2:
d.Age = EntitiesGenerator.ReadToInt32NullableConvert(reader,j);
break;
case 3:
d.Name = EntitiesGenerator.ReadToString(reader,j);
break;
case 4:
d.Name = EntitiesGenerator.ReadToStringConvert(reader,j);
break;
case 5:
d.Weight = EntitiesGenerator.ReadToFloatNullable(reader,j);
break;
case 6:
d.Weight = EntitiesGenerator.ReadToFloatNullableConvert(reader,j);
break;
default:
break;
}
}
添加 reader 字段判断缓存
添加缓存,减少重复生成
var h = reader.GetColumnHash();
if (!tokenCache.TryGetValue(h, out var ss))
{
var s = new List<int>(reader.FieldCount);
for (int i = 0; i < reader.FieldCount; i++)
结果
BenchmarkDotNet v0.13.12, Windows 10 (10.0.19045.4651/22H2/2022Update)
Intel Core i7-10700 CPU 2.90GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.100-preview.5.24307.3
[Host] : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX2
DefaultJob : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX2
| Method | Categories | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|---|
| SourceGeneratorMappingFirst | 1 | 434.7 ns | 8.67 ns | 7.69 ns | 0.84 | 0.02 | 0.0401 | 0.0396 | - | 336 B | 1.20 |
| SetClassFirst | 1 | 516.8 ns | 9.86 ns | 10.55 ns | 1.00 | 0.00 | 0.0334 | 0.0324 | 0.0019 | 280 B | 1.00 |
| DapperMappingFirst AOT | 1 | 1,333.4 ns | 2.49 ns | 2.33 ns | 2.58 | 0.06 | 0.0324 | - | - | 280 B | 1.00 |
| DapperMappingFirst | 1 | 1,421.4 ns | 3.08 ns | 2.88 ns | 2.84 | 0.12 | 0.0496 | - | - | 416 B | 1.49 |
| SetClass | 1000 | 8,139.8 ns | 130.22 ns | 115.43 ns | 1.00 | 0.00 | 6.7902 | 1.6937 | - | 56840 B | 1.00 |
| DapperMapping AOT | 1000 | 16,373.8 ns | 275.34 ns | 244.08 ns | 2.01 | 0.05 | 6.7749 | 0.9460 | - | 56840 B | 1.00 |
| SourceGeneratorMapping | 1000 | 20,911.5 ns | 77.69 ns | 60.65 ns | 2.57 | 0.04 | 6.7749 | 1.6785 | - | 56896 B | 1.00 |
| DapperMapping | 1000 | 48,707.3 ns | 430.05 ns | 381.23 ns | 5.67 | 0.29 | 12.5122 | 2.0752 | - | 105120 B | 1.85 |
SourceGenerator 生成db to class代码优化结果记录的更多相关文章
- java生成db文件
工作中遇到一个需求,就是需要把mysql里的一些表数据生成db文件,给客户端使用,客户端使用sqlite数据库: 首先我们需要在项目中添加Sqlite JDBC 依赖 <dependency&g ...
- Linux中生成Core Dump系统异常信息记录文件的教程
Linux中生成Core Dump系统异常信息记录文件的教程 http://www.jb51.net/LINUXjishu/473351.html
- Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer 关于Newtonsoft.Json,LINQ to JSON的一个小demo mysql循环插入数据、生成随机数及CONCAT函数 .NET记录-获取外网IP以及判断该IP是属于网通还是电信 Guid的生成和数据修整(去除空格和小写字符)
Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer Advanced Installer :Free for 30 da ...
- IntelliJ IDEA 类和方法注释的生成以及Javadoc的简单使用记录
idea,设置类注释和,方法注释的常见的设置方法(不同的版本设置方法有所偏差,简单记录一些目前自己在使用的方法,) 方法注释:在keyMap中搜索Fix doc comment ,后点击右键设置一个快 ...
- Django创建表时报错django.db.utils.InternalError: (1366问题解决记录
问题出现 执行Python manage.py makemigrations生成创建表的py文件 执行python manage.py migrate创建数据表 界面出现报错 问题原因 网上搜索原因, ...
- CORE EF生成ORACLE数据库模型报错问题记录
需求:最近在新开发一套在LINUX运行的API接口,需要用到net core api框架以及oracle数据库,首先需要解决的就是连接数据库问题,由于是DBFirst 加上之前很多老表不规范,导致了c ...
- python DB.fetchall()--获取数据库所有记录列表
查询到的数据格式为列表: 多个元素的列表:
- 8、android代码优化技术记录
1.length.length().size的优化 举例: int array_one[] = {1,2,3,4,5,6,7,8,9,10}; int array_two[] = {1,2,3,4,5 ...
- Inverse是hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录
<set name ='students' table="students_table" inverse='false'(默认不用写) > <key column ...
- mysql快速生成truncate脚本清空数据库表记录
语句格式: select CONCAT('truncate TABLE ',table_schema,'.',TABLE_NAME, ';') from INFORMATION_SCHEMA.TABL ...
随机推荐
- C++笔记(5)浅拷贝和深拷贝
1. 定义 浅拷贝(shallow copy):多个对象共用同一块资源,同一块资源释放多次,崩溃或者内存泄漏 深拷贝(deep copy):每个对象共同拥有自己的资源,必须显式提供拷贝构造函数和赋值运 ...
- 美团一面:什么是CAS?有什么优缺点?我说我只用过AtomicInteger。。。。
引言 传统的并发控制手段,如使用synchronized关键字或者ReentrantLock等互斥锁机制,虽然能够有效防止资源的竞争冲突,但也可能带来额外的性能开销,如上下文切换.锁竞争导致的线程阻塞 ...
- 一个或多个C文件编译KO
参考文档:.c文件如何编译为ko的MAKEFILE文件编写 - young525 - 博客园 (cnblogs.com) 文档组织结构 header目录:存放头文件 source目录:存放源文件 单个 ...
- 剑指Offer-62.二叉搜索树的第k个结点(C++/Java)
题目: 给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. 分析: 二叉搜索树的中序遍历结果正好是按数值升序排列的结 ...
- 关于 ulimit 的两个天坑
稍微有点 Linux 经验的人一定会遇到过 "Too many open files" 错误,这个错误本质是 ulimit 设置不合理导致的.关于 ulimit 设置,有哪些需要注 ...
- 机器学习策略篇:详解清除标注错误的数据(Cleaning up Incorrectly labeled data)
清除标注错误的数据 监督学习问题的数据由输入\(x\)和输出标签 \(y\) 构成,如果观察一下的数据,并发现有些输出标签 \(y\) 是错的.的数据有些标签是错的,是否值得花时间去修正这些标签呢? ...
- zabbix---监控Oracle12c数据库
使用插件:orabbix用于监控oracle实例的zabbix插件 orabbix插件下载地址:http://www.smartmarmot.com/product/orabbix/download/ ...
- 十大java应用服务器(web server)总结
java应用服务器(web server),是指运行java程序的web应用服务器软件,不包括nginx.Apache等通用web服务器软件. 一.Tomcat Tomcat是Apache 软件基金会 ...
- 2019南京区域赛ABCHJK题解 & KM-bfs(O(n^3))板子
A.Hard Problem 题目大意:给你一个数n,然后让你计算一个子集大小,这个大小的子集要保证一定存在一个数是另一个数的约数,求出这个最小的数. 做法:显然后面的\(\frac{n}{2}\)个 ...
- ARM GIC 系列文章学习(转)
原文来自:骏的世界 ARM GIC(一) cortex-A 处理器中断简介 对于ARM的处理器,中断给处理器提供了触觉,使处理器能够感知到外界的变化,从而实时的处理.本系列博文,是以ARM corte ...