优化

上一次实验 代码写的较为随意,本次穷尽所学,优化了一把,

不过果然还是没 比过 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代码优化结果记录的更多相关文章

  1. java生成db文件

    工作中遇到一个需求,就是需要把mysql里的一些表数据生成db文件,给客户端使用,客户端使用sqlite数据库: 首先我们需要在项目中添加Sqlite JDBC 依赖 <dependency&g ...

  2. Linux中生成Core Dump系统异常信息记录文件的教程

    Linux中生成Core Dump系统异常信息记录文件的教程 http://www.jb51.net/LINUXjishu/473351.html

  3. 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 ...

  4. IntelliJ IDEA 类和方法注释的生成以及Javadoc的简单使用记录

    idea,设置类注释和,方法注释的常见的设置方法(不同的版本设置方法有所偏差,简单记录一些目前自己在使用的方法,) 方法注释:在keyMap中搜索Fix doc comment ,后点击右键设置一个快 ...

  5. Django创建表时报错django.db.utils.InternalError: (1366问题解决记录

    问题出现 执行Python manage.py makemigrations生成创建表的py文件 执行python manage.py migrate创建数据表 界面出现报错 问题原因 网上搜索原因, ...

  6. CORE EF生成ORACLE数据库模型报错问题记录

    需求:最近在新开发一套在LINUX运行的API接口,需要用到net core api框架以及oracle数据库,首先需要解决的就是连接数据库问题,由于是DBFirst 加上之前很多老表不规范,导致了c ...

  7. python DB.fetchall()--获取数据库所有记录列表

    查询到的数据格式为列表: 多个元素的列表:

  8. 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 ...

  9. Inverse是hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录

    <set name ='students' table="students_table" inverse='false'(默认不用写) > <key column ...

  10. mysql快速生成truncate脚本清空数据库表记录

    语句格式: select CONCAT('truncate TABLE ',table_schema,'.',TABLE_NAME, ';') from INFORMATION_SCHEMA.TABL ...

随机推荐

  1. vue侦听器 - watch

    使用watch来侦听data中数据的变化,watch中的属性一定是data 中已经存在的数据. 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够 ...

  2. 美团面试:说说Netty的零拷贝技术?

    零拷贝技术(Zero-Copy)是一个大家耳熟能详的技术名词了,它主要用于提升 IO(Input & Output)的传输性能. 那么问题来了,为什么零拷贝技术能提升 IO 性能? 1.零拷贝 ...

  3. C# .NET 拉卡拉支付接口解析 付款码支付 条码支付

    C# .NET 拉卡拉支付接口解析 付款码支付  条码支付 被扫 反扫 刷卡支付 B扫C. 简要: 1.测试环境给的私钥是PKCS8.签名用. 2.CRT证书用X509Certificate2 读取出 ...

  4. C#.NET HTTP Request 跳过自签名证书校验。

    public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain ...

  5. LangChain让LLM带上记忆

    最近两年,我们见识了"百模大战",领略到了大型语言模型(LLM)的风采,但它们也存在一个显著的缺陷:没有记忆. 在对话中,无法记住上下文的 LLM 常常会让用户感到困扰.本文探讨如 ...

  6. JavaScript实现防抖节流函数

    review 防抖函数 防抖函数一般是短时间内多次触发,但是只有最后一次触发结束后的delay秒内会去执行相对应的处理函数. 相当于一个赛道里面一次只能跑一辆赛车,如果此时已经有一辆赛车在跑道里面跑, ...

  7. Java序列化和反序列化 Serializable BeanUtils.copyProperties赋值属性方法

    Java序列化和反序列化 Serializable BeanUtils.copyProperties赋值属性方法 package com.example.core.mydemo.java; impor ...

  8. FreeRTOS简单内核实现7 阻塞链表

    0.思考与回答 0.1.思考一 如何处理进入阻塞状态的任务? 为了让 RTOS 支持多优先级,我们创建了多个就绪链表(数组形式),用每一个就绪链表表示一个优先级,对于阻塞状态的任务显然要从就绪链表中移 ...

  9. golang如何使用指针灵活操作内存?unsafe包原理解析

    Hi 你好,我是k哥.一个大厂工作6年,还在继续搬砖的后端程序员. 我们都知道,C/C++提供了强大的万能指针void*,任何类型的指针都可以和万能指针相互转换.并且指针还可以进行加减等算数操作.那么 ...

  10. TI AM64x开发板规格书(双核ARM Cortex-A53 + 单/四核Cortex-R5F + 单核Cortex-M4F,主频1GHz)

    1 评估板简介 创龙科技TL64x-EVM是一款基于TI Sitara系列AM64x双核ARM Cortex-A53 + 单/四核Cortex-R5F + 单核Cortex-M4F多核处理器设计的高性 ...