SourceGenerator 生成 db to class 代码优化结果记录
作者:八苦-瞿昙
- 2024-10-18 中国台湾
本文字数:1872 字
阅读完需:约 6 分钟
优化
上一次实验 代码写的较为随意,本次穷尽所学,优化了一把,
不过果然还是没 比过 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
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 4
版权声明: 本文为 InfoQ 作者【八苦-瞿昙】的原创文章。
原文链接:【http://xie.infoq.cn/article/06d8453fa5204f44521c07ec8】。文章转载请联系作者。
八苦-瞿昙
关注
一个假和尚,不懂人情世故。 2018-11-23 加入
会点点技术,能写些代码,只爱静静。 g hub: https://github.com/fs7744 黑历史:https://www.cnblogs.com/fs7744
评论