Skip to content

Commit b7fc494

Browse files
committed
chore: benchmarks without vs. with-xml vs. with-json
1 parent f5e394b commit b7fc494

File tree

5 files changed

+187
-49
lines changed

5 files changed

+187
-49
lines changed

BlazarTech.QueryableValues.sln

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QueryableValues.SqlServer.E
3030
EndProject
3131
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QueryableValues.SqlServer.Tests.EFCore7", "tests\QueryableValues.SqlServer.Tests.EFCore7\QueryableValues.SqlServer.Tests.EFCore7.csproj", "{D5293D2F-4649-4A2B-A50D-E7DBD4AA4A5C}"
3232
EndProject
33+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QueryableValues.SqlServer.Benchmarks", "benchmarks\QueryableValues.SqlServer.Benchmarks\QueryableValues.SqlServer.Benchmarks.csproj", "{99FE31A0-BC7E-412C-82E2-DA19E8B68613}"
34+
EndProject
3335
Global
3436
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3537
Debug|Any CPU = Debug|Any CPU
@@ -110,6 +112,12 @@ Global
110112
{D5293D2F-4649-4A2B-A50D-E7DBD4AA4A5C}.Test_All|Any CPU.Build.0 = Test_All|Any CPU
111113
{D5293D2F-4649-4A2B-A50D-E7DBD4AA4A5C}.Test|Any CPU.ActiveCfg = Test|Any CPU
112114
{D5293D2F-4649-4A2B-A50D-E7DBD4AA4A5C}.Test|Any CPU.Build.0 = Test|Any CPU
115+
{99FE31A0-BC7E-412C-82E2-DA19E8B68613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
116+
{99FE31A0-BC7E-412C-82E2-DA19E8B68613}.Release|Any CPU.ActiveCfg = Release|Any CPU
117+
{99FE31A0-BC7E-412C-82E2-DA19E8B68613}.Release|Any CPU.Build.0 = Release|Any CPU
118+
{99FE31A0-BC7E-412C-82E2-DA19E8B68613}.Test_All|Any CPU.ActiveCfg = Release|Any CPU
119+
{99FE31A0-BC7E-412C-82E2-DA19E8B68613}.Test_All|Any CPU.Build.0 = Release|Any CPU
120+
{99FE31A0-BC7E-412C-82E2-DA19E8B68613}.Test|Any CPU.ActiveCfg = Release|Any CPU
113121
EndGlobalSection
114122
GlobalSection(SolutionProperties) = preSolution
115123
HideSolutionNode = FALSE

benchmarks/QueryableValues.SqlServer.Benchmarks/ContainsBenchmarks.cs

Lines changed: 146 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,43 @@
44
using BlazarTech.QueryableValues;
55
using Microsoft.Data.SqlClient;
66
using Microsoft.EntityFrameworkCore;
7+
using System.Text;
78

89
namespace QueryableValues.SqlServer.Benchmarks;
910

10-
[SimpleJob(RunStrategy.Monitoring, warmupCount: 1, targetCount: 25, invocationCount: 200)]
11+
//[SimpleJob(RunStrategy.Monitoring, warmupCount: 1, iterationCount: 25, invocationCount: 200)]
12+
//[SimpleJob(RunStrategy.Monitoring, warmupCount: 1, iterationCount: 6, invocationCount: 200)]
13+
[SimpleJob(RunStrategy.Monitoring, warmupCount: 1, iterationCount: 6, invocationCount: 32)]
1114
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
1215
[GcServer(true), MemoryDiagnoser]
1316
public class ContainsBenchmarks
1417
{
15-
#pragma warning disable CS8618
16-
private IQueryable<Int32Entity> _int32Query;
17-
private IQueryable<GuidEntity> _guidQuery;
18-
private IQueryable<Int32Entity> _queryableValuesInt32Query;
19-
private IQueryable<GuidEntity> _queryableValuesGuidQuery;
20-
#pragma warning restore CS8618
21-
22-
[Params(2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096)]
18+
private IQueryable<Int32Entity> _int32Query = default!;
19+
private IQueryable<GuidEntity> _guidQuery = default!;
20+
private IQueryable<StringEntity> _stringQuery = default!;
21+
22+
private IQueryable<Int32Entity> _queryableValuesJsonInt32Query = default!;
23+
private IQueryable<GuidEntity> _queryableValuesJsonGuidQuery = default!;
24+
private IQueryable<StringEntity> _queryableValuesJsonStringQuery = default!;
25+
26+
private IQueryable<Int32Entity> _queryableValuesXmlInt32Query = default!;
27+
private IQueryable<GuidEntity> _queryableValuesXmlGuidQuery = default!;
28+
private IQueryable<StringEntity> _queryableValuesXmlStringQuery = default!;
29+
30+
public enum DataType
31+
{
32+
Int32,
33+
Guid,
34+
String
35+
}
36+
37+
[Params(DataType.Int32, DataType.Guid, DataType.String)]
38+
//[Params(DataType.String)]
39+
public DataType Type { get; set; }
40+
41+
//[Params(512)]
42+
//[Params(2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096)]
43+
[Params(2, 8, 32, 128, 512, 2048)]
2344
public int NumberOfValues { get; set; }
2445

2546
private IEnumerable<int> GetIntValues()
@@ -38,87 +59,174 @@ private IEnumerable<Guid> GetGuidValues()
3859
}
3960
}
4061

62+
private IEnumerable<string> GetStringValues()
63+
{
64+
var sb = new StringBuilder();
65+
66+
for (int i = 0; i < NumberOfValues; i++)
67+
{
68+
sb.Clear();
69+
var length = Random.Shared.Next(0, 50);
70+
for (int x = 0; x < length; x++)
71+
{
72+
sb.Append((char)Random.Shared.Next(32, 126));
73+
}
74+
yield return sb.ToString();
75+
}
76+
}
77+
4178
[GlobalSetup]
4279
public void GlobalSetup()
4380
{
4481
Console.WriteLine("Initializing...");
4582

46-
var dbContext = new MyDbContext();
83+
var dbContextXml = new MyDbContext(SerializationOptions.UseXml);
84+
var dbContextJson = new MyDbContext(SerializationOptions.UseJson);
4785

4886
#region Init db
4987
{
50-
var wasCreated = dbContext.Database.EnsureCreated();
88+
var wasCreated = dbContextXml.Database.EnsureCreated();
5189

5290
if (wasCreated)
5391
{
54-
for (int i = 0; i < 1000; i++)
92+
const int itemsCount = 1000;
93+
94+
for (int i = 0; i < itemsCount; i++)
95+
{
96+
dbContextXml.Add(new Int32Entity());
97+
dbContextXml.Add(new GuidEntity());
98+
}
99+
100+
var i2 = 0;
101+
102+
foreach (var value in GetStringValues())
55103
{
56-
dbContext.Add(new Int32Entity());
57-
dbContext.Add(new GuidEntity());
104+
i2++;
105+
106+
dbContextXml.Add(new StringEntity { Id = $"{value}{i2}" });
107+
108+
if (i2 == itemsCount)
109+
{
110+
break;
111+
}
58112
}
59113

60-
dbContext.SaveChanges();
114+
dbContextXml.SaveChanges();
61115
}
62116

63117
var versionParam = new SqlParameter("@Version", System.Data.SqlDbType.NVarChar, -1)
64118
{
65119
Direction = System.Data.ParameterDirection.Output
66120
};
67121

68-
dbContext.Database.ExecuteSqlRaw("SET @Version = @@VERSION;", versionParam);
122+
dbContextXml.Database.ExecuteSqlRaw("SET @Version = @@VERSION;", versionParam);
69123

70124
Console.WriteLine(versionParam.Value);
71125

72-
dbContext.Database.ExecuteSqlRaw("DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;");
126+
dbContextXml.Database.ExecuteSqlRaw("DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;");
73127
}
74128
#endregion
75129

76130
#region Int32 Queries
77131
{
78132
var intValues = GetIntValues();
79133

80-
_int32Query = dbContext.Int32Entities
134+
_int32Query = dbContextXml.Int32Entities
81135
.Where(i => intValues.Contains(i.Id));
82136

83-
_queryableValuesInt32Query = dbContext.Int32Entities
84-
.Where(i => dbContext.AsQueryableValues(intValues).Contains(i.Id));
137+
_queryableValuesXmlInt32Query = dbContextXml.Int32Entities
138+
.Where(i => dbContextXml.AsQueryableValues(intValues).Contains(i.Id));
139+
140+
_queryableValuesJsonInt32Query = dbContextJson.Int32Entities
141+
.Where(i => dbContextJson.AsQueryableValues(intValues).Contains(i.Id));
85142
}
86143
#endregion
87144

88145
#region Guid Queries
89146
{
90147
var guidValues = GetGuidValues();
91148

92-
_guidQuery = dbContext.GuidEntities
149+
_guidQuery = dbContextXml.GuidEntities
93150
.Where(i => guidValues.Contains(i.Id));
94151

95-
_queryableValuesGuidQuery = dbContext.GuidEntities
96-
.Where(i => dbContext.AsQueryableValues(guidValues).Contains(i.Id));
152+
_queryableValuesXmlGuidQuery = dbContextXml.GuidEntities
153+
.Where(i => dbContextXml.AsQueryableValues(guidValues).Contains(i.Id));
154+
155+
_queryableValuesJsonGuidQuery = dbContextJson.GuidEntities
156+
.Where(i => dbContextJson.AsQueryableValues(guidValues).Contains(i.Id));
97157
}
98158
#endregion
99-
}
100159

101-
[Benchmark(Baseline = true), BenchmarkCategory("Int32")]
102-
public void Without_Int32()
103-
{
104-
_int32Query.Any();
160+
#region String Queries
161+
{
162+
var stringValues = GetStringValues();
163+
164+
_stringQuery = dbContextXml.StringEntities
165+
.Where(i => stringValues.Contains(i.Id));
166+
167+
_queryableValuesXmlStringQuery = dbContextXml.StringEntities
168+
.Where(i => dbContextXml.AsQueryableValues(stringValues, true).Contains(i.Id));
169+
170+
_queryableValuesJsonStringQuery = dbContextJson.StringEntities
171+
.Where(i => dbContextJson.AsQueryableValues(stringValues, true).Contains(i.Id));
172+
}
173+
#endregion
105174
}
106175

107-
[Benchmark, BenchmarkCategory("Int32")]
108-
public void With_Int32()
176+
[Benchmark(Baseline = true)]
177+
public void Without()
109178
{
110-
_queryableValuesInt32Query.Any();
179+
switch (Type)
180+
{
181+
case DataType.Int32:
182+
_int32Query.Any();
183+
break;
184+
case DataType.Guid:
185+
_guidQuery.Any();
186+
break;
187+
case DataType.String:
188+
_stringQuery.Any();
189+
break;
190+
default:
191+
throw new NotImplementedException();
192+
}
111193
}
112194

113-
[Benchmark(Baseline = true), BenchmarkCategory("Guid")]
114-
public void Without_Guid()
195+
[Benchmark]
196+
public void WithXml()
115197
{
116-
_guidQuery.Any();
198+
switch (Type)
199+
{
200+
case DataType.Int32:
201+
_queryableValuesXmlInt32Query.Any();
202+
break;
203+
case DataType.Guid:
204+
_queryableValuesXmlGuidQuery.Any();
205+
break;
206+
case DataType.String:
207+
_queryableValuesXmlStringQuery.Any();
208+
break;
209+
default:
210+
throw new NotImplementedException();
211+
}
117212
}
118213

119-
[Benchmark, BenchmarkCategory("Guid")]
120-
public void With_Guid()
214+
[Benchmark]
215+
public void WithJson()
121216
{
122-
_queryableValuesGuidQuery.Any();
217+
switch (Type)
218+
{
219+
case DataType.Int32:
220+
_queryableValuesJsonInt32Query.Any();
221+
break;
222+
case DataType.Guid:
223+
_queryableValuesJsonGuidQuery.Any();
224+
break;
225+
case DataType.String:
226+
_queryableValuesJsonStringQuery.Any();
227+
break;
228+
default:
229+
throw new NotImplementedException();
230+
}
123231
}
124-
}
232+
}

benchmarks/QueryableValues.SqlServer.Benchmarks/MyDbContext.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
using BlazarTech.QueryableValues;
22
using Microsoft.EntityFrameworkCore;
3+
using System.ComponentModel.DataAnnotations;
34

45
namespace QueryableValues.SqlServer.Benchmarks
56
{
67
public class MyDbContext : DbContext
78
{
8-
#pragma warning disable CS8618
9-
public DbSet<Int32Entity> Int32Entities { get; set; }
10-
public DbSet<GuidEntity> GuidEntities { get; set; }
11-
#pragma warning restore CS8618
9+
private readonly SerializationOptions _serializationOptions;
10+
11+
public DbSet<Int32Entity> Int32Entities { get; set; } = default!;
12+
public DbSet<GuidEntity> GuidEntities { get; set; } = default!;
13+
public DbSet<StringEntity> StringEntities { get; set; } = default!;
14+
15+
public MyDbContext(SerializationOptions serializationOptions)
16+
{
17+
_serializationOptions = serializationOptions;
18+
}
1219

1320
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
1421
{
1522
optionsBuilder.UseSqlServer(
16-
@"Server=.\SQLEXPRESS;Integrated Security=true;Database=QueryableValuesBenchmarks",
17-
builder => builder.UseQueryableValues()
23+
@"Server=.\SQLEXPRESS;Integrated Security=true;Database=QueryableValuesBenchmarks;Encrypt=False;",
24+
builder => builder.UseQueryableValues(options => options.Serialization(_serializationOptions))
1825
);
1926
}
2027

@@ -33,4 +40,10 @@ public class GuidEntity
3340
{
3441
public Guid Id { get; set; }
3542
}
43+
44+
public class StringEntity
45+
{
46+
[MaxLength(100)]
47+
public string Id { get; set; } = default!;
48+
}
3649
}
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
using BenchmarkDotNet.Running;
1+
using BenchmarkDotNet.Configs;
2+
using BenchmarkDotNet.Running;
23

34
namespace QueryableValues.SqlServer.Benchmarks;
45

56
class Program
67
{
78
static void Main(string[] args)
89
{
9-
var summary = BenchmarkRunner.Run<ContainsBenchmarks>();
10+
var config = new ManualConfig();
11+
12+
config.Add(DefaultConfig.Instance);
13+
config.WithOptions(ConfigOptions.DisableOptimizationsValidator);
14+
15+
BenchmarkRunner.Run<ContainsBenchmarks>(config);
1016
}
1117
}

benchmarks/QueryableValues.SqlServer.Benchmarks/QueryableValues.SqlServer.Benchmarks.csproj

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
12-
<PackageReference Include="BlazarTech.QueryableValues.SqlServer" Version="6.3.0" />
13-
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
11+
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
12+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.4" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\..\src\QueryableValues.SqlServer.EFCore7\QueryableValues.SqlServer.EFCore7.csproj" />
1417
</ItemGroup>
1518

1619
</Project>

0 commit comments

Comments
 (0)