Location>code7788 >text

SourceGenerator generates db to class code optimization results logs

Popularity:762 ℃/2024-08-02 11:36:02

make superior

The last experiment The code was written in a rather random manner, but this time we have optimized it to the best of our knowledge.

But it still doesn't beat Dapper aot, even though it doesn't use the Interceptor, but theoretically its optimization shouldn't be that far off.

Knowledge gap quite a bit ah, can not understand Dapper aot utilize what posture lead, there are gods can teach?

optimal point

Reduced type judgment

Make type judgments in advance and use switch cases to reduce judgments during generation.

beforehand

 var needConvert = typeof(string) != (i);
((d,r) =>  = (r,j,needConvert));

beyond

     switch (name)
    {
        
    case "age":
        (type == typeof(int) ? 1 : 2); 
        break;


    switch (ss[j])
    {
        
    case 1:
         = EntitiesGenerator.ReadToInt32Nullable(reader,j);
        break;
    case 2:
         = EntitiesGenerator.ReadToInt32NullableConvert(reader,j);
        break;

Avoid generating delegates

Remove the use of delegate generation

beforehand

var s = new List<Action<, IDataReader>>();
for (int i = 0; i < ; i++)
{
    var j = i;
    switch ((j).ToLower())
    {
        
        case "age": 
        {
            // int?
            
            var needConvert = typeof(int) != (i);
            ((d,r) =>  = DBExtensions.ReadToInt32Nullable(r,j,needConvert));
             
        }
        break;
        case "name": 
        {
            // string
            
            var needConvert = typeof(string) != (i);
            ((d,r) =>  = (r,j,needConvert));
             
        }
        break;
        case "weight": 
        {
            // float?
            
            var needConvert = typeof(float) != (i);
            ((d,r) =>  = (r,j,needConvert));
             
        }
        break;
        default:
            break;
    }
}
while (())
{
    var d = new ();
    foreach (var item in s)
    {
        item?.Invoke(d,reader);
    }
    yield return d;
}

beyond

var s = new List<int>();
for (int i = 0; i < ; i++)
{
    var name = (i).ToLower();
    var type = (i);
    switch (name)
    {
        
    case "age":
        (type == typeof(int) ? 1 : 2); 
        break;

    case "name":
        (type == typeof(string) ? 3 : 4); 
        break;

    case "weight":
        (type == typeof(float) ? 5 : 6); 
        break;

        default:
            break;
    }
}
ss = ();

var d = new ();
for (int j = 0; j < ; j++)
{
    switch (ss[j])
    {
        
    case 1:
         = EntitiesGenerator.ReadToInt32Nullable(reader,j);
        break;
    case 2:
         = EntitiesGenerator.ReadToInt32NullableConvert(reader,j);
        break;

    case 3:
         = (reader,j);
        break;
    case 4:
         = (reader,j);
        break;

    case 5:
         = (reader,j);
        break;
    case 6:
         = (reader,j);
        break;

        default:
            break;
    }
}

Add reader field to determine caching

Add caching to reduce duplicate generation

   var h = ();
   if (!(h, out var ss))
   {
       var s = new List<int>();
       for (int i = 0; i < ; i++)

in the end


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