11using BenchmarkDotNet . Attributes ;
22using BenchmarkDotNet . Jobs ;
33using Dapper ;
4+ using Gedaq . Common . Enums ;
45using Npgsql ;
56using NpgsqlBenchmark . Model ;
67using System . Collections . Generic ;
78using System . Data . Common ;
8- using System . Linq ;
99using System . Threading . Tasks ;
1010
1111namespace NpgsqlBenchmark . Benchmarks
1212{
13+ public class PersonFlat
14+ {
15+ public int Id { get ; set ; }
16+
17+ public string FirstName { get ; set ; }
18+
19+ public string MiddleName { get ; set ; }
20+
21+ public string LastName { get ; set ; }
22+
23+ [ Gedaq . Common . Attributes . IgnoreProperty ( ) ]
24+ public Identification Identification { get ; set ; }
25+ }
26+
1327 [ MemoryDiagnoser ]
1428 [ SimpleJob ( RuntimeMoniker . Net10_0 ) ]
15- [ HideColumns ( "Error" , "StdDev" , "Median" , "RatioSD" , "Gen0" , "Gen1" , "Gen2" ) ]
1629 public partial class CompareDapper : PostgresBenchmark
1730 {
1831 private NpgsqlConnection _connection ;
1932
20- [ Params ( 0 ) ]
21- public int Size ;
33+ [ Params ( 10 , 20 , 30 ) ]
34+ public int Iterations ;
2235
2336 [ GlobalSetup ]
2437 public async Task GlobalSetup ( )
@@ -55,35 +68,37 @@ public void IterationCleanup()
5568 }
5669 }
5770
58- [ Gedaq . Npgsql . Attributes . Query (
59- @"
71+ [ Benchmark ( Baseline = true , Description = "Dapper" ) ]
72+ public void Dapper ( )
73+ {
74+ for ( int i = 0 ; i < Iterations ; i ++ )
75+ {
76+ var persons = _connection . Query < Person , Identification , Person > ( @"
6077SELECT
6178 p.id,
6279 p.firstname,
63- ~StartInner::Identification:id~
64- i.id,
65- i.typename,
66- ~EndInner::Identification~
6780 p.middlename,
68- p.lastname
81+ p.lastname,
82+ p.identification_id,
83+ i.typename
6984FROM person p
7085LEFT JOIN identification i ON i.id = p.identification_id
71- WHERE p.id >= $1
7286" ,
73- "GetAllPerson" ,
74- typeof ( Person ) ) ,
75- Gedaq . Npgsql . Attributes . Parametr ( parametrType : typeof ( int ) , position : 1 )
76- ]
77- [ Benchmark ( Baseline = true , Description = $ "Gedaq.Npgsql", OperationsPerInvoke = 1_000 ) ]
78- public void Npgsql ( )
79- {
80- var persons = GetAllPerson ( _connection , 50_000 ) . ToList ( ) ;
87+ ( person , ident ) =>
88+ {
89+ person . Identification = ident ;
90+ return person ;
91+ } ,
92+ splitOn : "identification_id" ) . AsList ( ) ;
93+ }
8194 }
8295
83- [ Benchmark ( Description = "Dapper" , OperationsPerInvoke = 1_000 ) ]
84- public void Dapper ( )
96+ [ Benchmark ( Description = "Dapper Async" ) ]
97+ public async Task DapperAsync ( )
8598 {
86- var persons = _connection . Query < Person , Identification , Person > ( @"
99+ for ( int i = 0 ; i < Iterations ; i ++ )
100+ {
101+ var persons = ( await _connection . QueryAsync < Person , Identification , Person > ( @"
87102SELECT
88103 p.id,
89104 p.firstname,
@@ -93,21 +108,18 @@ public void Dapper()
93108 i.typename
94109FROM person p
95110LEFT JOIN identification i ON i.id = p.identification_id
96- WHERE p.id >= @id
97111" ,
98112( person , ident ) =>
99113{
100114 person . Identification = ident ;
101115 return person ;
102116} ,
103- new { id = 50_000 } ,
104- splitOn : "identification_id"
105- )
106- . ToList ( ) ;
117+ splitOn : "identification_id" ) ) . AsList ( ) ;
118+ }
107119 }
108120
109121 [ DapperAot ]
110- public static IEnumerable < Person > DapperAOTGetAllPerson ( DbConnection connection , int id ) => connection . Query < Person , Identification , Person > (
122+ public static IEnumerable < Person > DapperAOTGetAllPerson ( DbConnection connection ) => connection . Query < Person , Identification , Person > (
111123 @"SELECT
112124 p.id,
113125 p.firstname,
@@ -117,21 +129,136 @@ public static IEnumerable<Person> DapperAOTGetAllPerson(DbConnection connection,
117129 i.typename
118130FROM person p
119131LEFT JOIN identification i ON i.id = p.identification_id
120- WHERE p.id >= @id
121132" ,
122133( person , ident ) =>
123134{
124135 person . Identification = ident ;
125136 return person ;
126137} ,
127- new { id } ,
128- splitOn : "identification_id"
129- ) ;
138+ splitOn : "identification_id" ) ;
130139
131- [ Benchmark ( Description = "DapperAOT" , OperationsPerInvoke = 1_000 ) ]
140+ [ Benchmark ( Description = "DapperAOT" ) ]
132141 public void DapperAOT ( )
133142 {
134- var persons = DapperAOTGetAllPerson ( _connection , 50_000 ) . ToList ( ) ;
143+ for ( int i = 0 ; i < Iterations ; i ++ )
144+ {
145+ var persons = DapperAOTGetAllPerson ( _connection ) . AsList ( ) ;
146+ }
147+ }
148+
149+ [ DapperAot ]
150+ public static Task < IEnumerable < Person > > DapperAOTGetAllPersonAsync ( DbConnection connection ) => connection . QueryAsync < Person , Identification , Person > (
151+ @"SELECT
152+ p.id,
153+ p.firstname,
154+ p.middlename,
155+ p.lastname,
156+ p.identification_id,
157+ i.typename
158+ FROM person p
159+ LEFT JOIN identification i ON i.id = p.identification_id
160+ " ,
161+ ( person , ident ) =>
162+ {
163+ person . Identification = ident ;
164+ return person ;
165+ } ,
166+ splitOn : "identification_id" ) ;
167+
168+ [ Benchmark ( Description = "DapperAOT Async" ) ]
169+ public async Task DapperAOTAsync ( )
170+ {
171+ for ( int i = 0 ; i < Iterations ; i ++ )
172+ {
173+ var persons = ( await DapperAOTGetAllPersonAsync ( _connection ) ) . AsList ( ) ;
174+ }
175+ }
176+
177+ [ Gedaq . Npgsql . Attributes . Query (
178+ query : @"
179+ SELECT
180+ p.id,
181+ p.firstname,
182+ ~StartInner::Identification:id~
183+ i.id,
184+ i.typename,
185+ ~EndInner::Identification~
186+ p.middlename,
187+ p.lastname
188+ FROM person p
189+ LEFT JOIN identification i ON i.id = p.identification_id
190+ " ,
191+ methodName : "GetAllPerson" ,
192+ queryMapTypes : [ typeof ( Person ) ] ,
193+ methodType : MethodType . Sync | MethodType . Async ,
194+ asyncResultType : AsyncResult . ValueTask ) ]
195+ [ Benchmark ( Description = $ "Gedaq Static Sync") ]
196+ public void GedaqStatic ( )
197+ {
198+ for ( int i = 0 ; i < Iterations ; i ++ )
199+ {
200+ var persons = GetAllPerson ( _connection ) ;
201+ }
202+ }
203+
204+ [ Benchmark ( Description = $ "Gedaq Static Async") ]
205+ public async Task GedaqStaticAsync ( )
206+ {
207+ for ( int i = 0 ; i < Iterations ; i ++ )
208+ {
209+ var persons = await GetAllPersonAsync ( _connection ) ;
210+ }
211+ }
212+
213+ [ Gedaq . Npgsql . Attributes . Query (
214+ query : null ,
215+ methodName : "GetAllPersonDyn" ,
216+ queryMapTypes : [ typeof ( PersonFlat ) , typeof ( Identification ) ] ,
217+ overrideAliasPrefixs : [ "person_" , "identity_" ] ,
218+ methodType : MethodType . Sync | MethodType . Async ,
219+ asyncResultType : AsyncResult . ValueTask ) ]
220+ [ Benchmark ( Description = $ "Gedaq Dynamic Sync") ]
221+ public void GedaqDynamic ( )
222+ {
223+ for ( int i = 0 ; i < Iterations ; i ++ )
224+ {
225+ var persons = new List < PersonFlat > ( ) ;
226+
227+ GetAllPersonDyn ( _connection , @"
228+ SELECT
229+ p.id as person_id,
230+ p.firstname as person_firstname,
231+ p.middlename as person_middlename,
232+ p.lastname as person_lastname,
233+ i.id as identity_id,
234+ i.typename as identity_typename
235+ FROM person p
236+ LEFT JOIN identification i ON i.id = p.identification_id
237+ " ,
238+ ( person , indetity ) => { person . Identification = indetity ; persons . Add ( person ) ; } ) ;
239+ }
240+ }
241+
242+ [ Benchmark ( Description = $ "Gedaq Dynamic Async") ]
243+ public async Task GedaqDynamicAsync ( )
244+ {
245+ for ( int i = 0 ; i < Iterations ; i ++ )
246+ {
247+ var persons = new List < PersonFlat > ( ) ;
248+
249+ await GetAllPersonDynAsync ( _connection , @"
250+ SELECT
251+ p.id as person_id,
252+ p.firstname as person_firstname,
253+ p.middlename as person_middlename,
254+ p.lastname as person_lastname,
255+ i.id as identity_id,
256+ i.typename as identity_typename
257+ FROM person p
258+ LEFT JOIN identification i ON i.id = p.identification_id
259+ " ,
260+ ( person , indetity ) => { person . Identification = indetity ; persons . Add ( person ) ; } ) ;
261+ }
135262 }
136263 }
137264}
0 commit comments