Skip to content

Commit 575d44a

Browse files
fix: write benchmarks
1 parent c614cef commit 575d44a

18 files changed

Lines changed: 338 additions & 59 deletions

File tree

benchmark/BenchmarkRunner/Benchmarks/BaseReadBenchmark.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ int QueriesToSubmit
99

1010
public abstract class BaseReadBenchmark
1111
{
12+
1213
[IterationSetup]
1314
public static void IterationSetup() => Helpers.InvokeGarbageCollection();
1415
public abstract Task Sqlc_GetCustomerOrders();

benchmark/BenchmarkRunner/Benchmarks/BaseWriteBenchmark.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ int BatchSize
55

66
public abstract class BaseWriteBenchmark
77
{
8+
public const int OrderIdsCountForSetup = 1000;
9+
public const int ProductIdsCountForSetup = 1000;
10+
811
public static DatabaseSeedConfig GetSeedConfig() => new(
912
CustomerCount: 500,
1013
ProductsPerCategory: 150,

benchmark/BenchmarkRunner/Benchmarks/MysqlWriteBenchmark.cs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using MySqlConnector;
77
using MysqlEFCoreImpl;
88
using MysqlSqlcImpl;
9+
using NUnit.Framework;
910

1011
namespace BenchmarkRunner.Benchmarks;
1112

@@ -16,39 +17,43 @@ namespace BenchmarkRunner.Benchmarks;
1617
[CategoriesColumn]
1718
public class MysqlWriteBenchmark : BaseWriteBenchmark
1819
{
20+
private const int _totalRecordsForSetup = 200_000;
1921
private static readonly string _connectionString = Config.GetMysqlConnectionString();
2022
private readonly QuerySql _sqlcImpl = new(_connectionString);
2123
private readonly Queries _efCoreImpl = new(new SalesDbContext(_connectionString), useTracking: false);
22-
private List<QuerySql.AddOrderItemsArgs> _testOrderItems = null!;
24+
25+
private List<QuerySql.AddOrderItemsArgs> _sqlcTestOrderItems = null!;
26+
private List<Queries.AddOrderItemsArgs> _efCoreTestOrderItems = null!;
2327

2428
public static IEnumerable<WriteBenchmarkArgs> GetSqlcArguments()
2529
{
26-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 1_000);
27-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 5_000);
30+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 1_000);
31+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 5_000);
2832
}
2933

3034
[BenchmarkCategory("Write")]
3135
[Benchmark(Baseline = true, Description = "SQLC - AddOrderItems")]
3236
[ArgumentsSource(nameof(GetSqlcArguments))]
3337
public override async Task Sqlc_AddOrderItems(WriteBenchmarkArgs args)
3438
{
35-
await Helpers.InsertInBatchesAsync(_testOrderItems, args.BatchSize, _sqlcImpl.AddOrderItemsAsync);
39+
await Helpers.InsertInBatchesAsync(_sqlcTestOrderItems[..args.TotalRecords], args.BatchSize, _sqlcImpl.AddOrderItemsAsync);
40+
var result = await _sqlcImpl.GetOrderItemsCountAsync();
41+
Assert.That(result?.Cnt, Is.EqualTo(args.TotalRecords));
3642
}
3743

3844
public static IEnumerable<WriteBenchmarkArgs> GetEFCoreArguments()
3945
{
40-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 500);
46+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 500);
4147
}
4248

4349
[BenchmarkCategory("Write")]
4450
[Benchmark(Description = "EFCore - AddOrderItems")]
4551
[ArgumentsSource(nameof(GetEFCoreArguments))]
4652
public override async Task EFCore_AddOrderItems(WriteBenchmarkArgs args)
4753
{
48-
var batchArgs = _testOrderItems.Select(i => new Queries.AddOrderItemsArgs(
49-
i.OrderId, i.ProductId, i.Quantity, i.UnitPrice
50-
)).ToList();
51-
await Helpers.InsertInBatchesAsync(batchArgs, args.BatchSize, _efCoreImpl.AddOrderItems);
54+
await Helpers.InsertInBatchesAsync(_efCoreTestOrderItems[..args.TotalRecords], args.BatchSize, _efCoreImpl.AddOrderItems);
55+
var result = await _sqlcImpl.GetOrderItemsCountAsync();
56+
Assert.That(result?.Cnt, Is.EqualTo(args.TotalRecords));
5257
}
5358

5459
public static Func<Task> GetSeedMethod()
@@ -62,23 +67,42 @@ public static Func<Task> GetSeedMethod()
6267

6368
[GlobalSetup]
6469
public async Task GlobalSetup()
70+
{
71+
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: OrderIdsCountForSetup));
72+
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: ProductIdsCountForSetup));
73+
_sqlcTestOrderItems = GetSqlcTestOrderItemsAsync(orderIds, productIds);
74+
_efCoreTestOrderItems = GetEFCoreTestOrderItems(orderIds, productIds);
75+
}
76+
77+
[IterationSetup]
78+
public static void IterationSetup()
6579
{
66-
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
67-
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
80+
CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
81+
Helpers.InvokeGarbageCollection();
82+
}
6883

69-
_testOrderItems = [.. Enumerable.Range(0, 5000).Select(i => new QuerySql.AddOrderItemsArgs(
70-
OrderId: orderIds[i % orderIds.Count].OrderId,
71-
ProductId: productIds[i % productIds.Count].ProductId,
84+
private static List<QuerySql.AddOrderItemsArgs> GetSqlcTestOrderItemsAsync(
85+
List<QuerySql.GetOrderIdsRow> orderIds,
86+
List<QuerySql.GetProductIdsRow> productIds)
87+
{
88+
return [.. Enumerable.Range(0, _totalRecordsForSetup).Select(i => new QuerySql.AddOrderItemsArgs(
89+
OrderId: orderIds[i % OrderIdsCountForSetup].OrderId,
90+
ProductId: productIds[i % ProductIdsCountForSetup].ProductId,
7291
Quantity: Random.Shared.Next(1, 10),
7392
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
7493
))];
7594
}
7695

77-
[IterationSetup]
78-
public static void IterationSetup()
96+
private static List<Queries.AddOrderItemsArgs> GetEFCoreTestOrderItems(
97+
List<QuerySql.GetOrderIdsRow> orderIds,
98+
List<QuerySql.GetProductIdsRow> productIds)
7999
{
80-
CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
81-
Helpers.InvokeGarbageCollection();
100+
return [.. Enumerable.Range(0, _totalRecordsForSetup).Select(i => new Queries.AddOrderItemsArgs(
101+
OrderId: orderIds[i % OrderIdsCountForSetup].OrderId,
102+
ProductId: productIds[i % ProductIdsCountForSetup].ProductId,
103+
Quantity: Random.Shared.Next(1, 10),
104+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
105+
))];
82106
}
83107

84108
private static async Task CleanupWriteTableAsync(string connectionString)

benchmark/BenchmarkRunner/Benchmarks/PostgresqlWriteBenchmark.cs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using BenchmarkDotNet.Jobs;
44
using BenchmarkRunner.Utils;
55
using Npgsql;
6+
using NUnit.Framework;
67
using PostgresEFCoreImpl;
78
using PostgresSqlcImpl;
89

@@ -15,39 +16,42 @@ namespace BenchmarkRunner.Benchmarks;
1516
[CategoriesColumn]
1617
public class PostgresqlWriteBenchmark : BaseWriteBenchmark
1718
{
19+
private const int _totalRecordsForSetup = 200_000;
1820
private static readonly string _connectionString = Config.GetPostgresConnectionString();
1921
private readonly QuerySql _sqlcImpl = new(_connectionString);
2022
private readonly Queries _efCoreImpl = new(new SalesDbContext(_connectionString), useTracking: false);
21-
private List<QuerySql.AddOrderItemsArgs> _testOrderItems = null!;
23+
private List<QuerySql.AddOrderItemsArgs> _sqlcTestOrderItems = null!;
24+
private List<Queries.AddOrderItemsArgs> _efCoreTestOrderItems = null!;
2225

2326
public static IEnumerable<WriteBenchmarkArgs> GetSqlcArguments()
2427
{
25-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 1_000);
26-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 2_000);
28+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 1_000);
29+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 2_000);
2730
}
2831

2932
[BenchmarkCategory("Write")]
3033
[Benchmark(Baseline = true, Description = "SQLC - AddOrderItems")]
3134
[ArgumentsSource(nameof(GetSqlcArguments))]
3235
public override async Task Sqlc_AddOrderItems(WriteBenchmarkArgs args)
3336
{
34-
await Helpers.InsertInBatchesAsync(_testOrderItems, args.BatchSize, _sqlcImpl.AddOrderItemsAsync);
37+
await Helpers.InsertInBatchesAsync(_sqlcTestOrderItems[..args.TotalRecords], args.BatchSize, _sqlcImpl.AddOrderItemsAsync);
38+
var result = await _sqlcImpl.GetOrderItemsCountAsync();
39+
Assert.That(result?.Cnt, Is.EqualTo(args.TotalRecords));
3540
}
3641

3742
public static IEnumerable<WriteBenchmarkArgs> GetEFCoreArguments()
3843
{
39-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 500);
44+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 500);
4045
}
4146

4247
[BenchmarkCategory("Write")]
4348
[Benchmark(Description = "EFCore - AddOrderItems")]
4449
[ArgumentsSource(nameof(GetEFCoreArguments))]
4550
public override async Task EFCore_AddOrderItems(WriteBenchmarkArgs args)
4651
{
47-
var batchArgs = _testOrderItems.Select(i => new Queries.AddOrderItemsArgs(
48-
i.OrderId, i.ProductId, i.Quantity, i.UnitPrice
49-
)).ToList();
50-
await Helpers.InsertInBatchesAsync(batchArgs, args.BatchSize, _efCoreImpl.AddOrderItems);
52+
await Helpers.InsertInBatchesAsync(_efCoreTestOrderItems[..args.TotalRecords], args.BatchSize, _efCoreImpl.AddOrderItems);
53+
var result = await _sqlcImpl.GetOrderItemsCountAsync();
54+
Assert.That(result?.Cnt, Is.EqualTo(args.TotalRecords));
5155
}
5256

5357
public static Func<Task> GetSeedMethod()
@@ -62,15 +66,10 @@ public static Func<Task> GetSeedMethod()
6266
[GlobalSetup]
6367
public async Task GlobalSetup()
6468
{
65-
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
66-
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
67-
68-
_testOrderItems = [.. Enumerable.Range(0, 5000).Select(i => new QuerySql.AddOrderItemsArgs(
69-
OrderId: orderIds[i % orderIds.Count].OrderId,
70-
ProductId: productIds[i % productIds.Count].ProductId,
71-
Quantity: Random.Shared.Next(1, 10),
72-
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
73-
))];
69+
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: OrderIdsCountForSetup));
70+
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: ProductIdsCountForSetup));
71+
_sqlcTestOrderItems = GetSqlcTestOrderItemsAsync(orderIds, productIds);
72+
_efCoreTestOrderItems = GetEFCoreTestOrderItems(orderIds, productIds);
7473
}
7574

7675
[IterationSetup]
@@ -80,6 +79,30 @@ public static void IterationSetup()
8079
Helpers.InvokeGarbageCollection();
8180
}
8281

82+
private static List<QuerySql.AddOrderItemsArgs> GetSqlcTestOrderItemsAsync(
83+
List<QuerySql.GetOrderIdsRow> orderIds,
84+
List<QuerySql.GetProductIdsRow> productIds)
85+
{
86+
return [.. Enumerable.Range(0, _totalRecordsForSetup).Select(i => new QuerySql.AddOrderItemsArgs(
87+
OrderId: orderIds[i % OrderIdsCountForSetup].OrderId,
88+
ProductId: productIds[i % ProductIdsCountForSetup].ProductId,
89+
Quantity: Random.Shared.Next(1, 10),
90+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
91+
))];
92+
}
93+
94+
private static List<Queries.AddOrderItemsArgs> GetEFCoreTestOrderItems(
95+
List<QuerySql.GetOrderIdsRow> orderIds,
96+
List<QuerySql.GetProductIdsRow> productIds)
97+
{
98+
return [.. Enumerable.Range(0, _totalRecordsForSetup).Select(i => new Queries.AddOrderItemsArgs(
99+
OrderId: orderIds[i % OrderIdsCountForSetup].OrderId,
100+
ProductId: productIds[i % ProductIdsCountForSetup].ProductId,
101+
Quantity: Random.Shared.Next(1, 10),
102+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
103+
))];
104+
}
105+
83106
private static async Task CleanupWriteTableAsync(string connectionString)
84107
{
85108
using var connection = new NpgsqlConnection(connectionString);

benchmark/BenchmarkRunner/Benchmarks/SqliteReadBenchmark.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using BenchmarkRunner.Utils;
55
using EndToEndTests;
66
using NUnit.Framework;
7-
using NUnit.Framework.Legacy;
87
using SqliteEFCoreImpl;
98
using SqliteSqlcImpl;
109

benchmark/BenchmarkRunner/Benchmarks/SqliteWriteBenchmark.cs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using BenchmarkRunner.Utils;
55
using EndToEndTests;
66
using Microsoft.Data.Sqlite;
7+
using NUnit.Framework;
78
using SqliteEFCoreImpl;
89
using SqliteSqlcImpl;
910

@@ -16,39 +17,42 @@ namespace BenchmarkRunner.Benchmarks;
1617
[CategoriesColumn]
1718
public class SqliteWriteBenchmark : BaseWriteBenchmark
1819
{
20+
private const int _totalRecordsForSetup = 200_000;
1921
private static readonly string _connectionString = Config.GetSqliteConnectionString();
2022
private readonly QuerySql _sqlcImpl = new(_connectionString);
2123
private readonly Queries _efCoreImpl = new(new SalesDbContext(_connectionString), useTracking: false);
22-
private List<QuerySql.AddOrderItemsArgs> _testOrderItems = null!;
24+
private List<QuerySql.AddOrderItemsArgs> _sqlcTestOrderItems = null!;
25+
private List<Queries.AddOrderItemsArgs> _efCoreTestOrderItems = null!;
2326

2427
public static IEnumerable<WriteBenchmarkArgs> GetSqlcArguments()
2528
{
26-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 50);
27-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 100);
29+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 50);
30+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 100);
2831
}
2932

3033
[BenchmarkCategory("Write")]
3134
[Benchmark(Baseline = true, Description = "SQLC - AddOrderItems")]
3235
[ArgumentsSource(nameof(GetSqlcArguments))]
3336
public override async Task Sqlc_AddOrderItems(WriteBenchmarkArgs args)
3437
{
35-
await Helpers.InsertInBatchesAsync(_testOrderItems, args.BatchSize, _sqlcImpl.AddOrderItemsAsync);
38+
await Helpers.InsertInBatchesAsync(_sqlcTestOrderItems[..args.TotalRecords], args.BatchSize, _sqlcImpl.AddOrderItemsAsync);
39+
var result = await _sqlcImpl.GetOrderItemsCountAsync();
40+
Assert.That(result?.Cnt, Is.EqualTo(args.TotalRecords));
3641
}
3742

3843
public static IEnumerable<WriteBenchmarkArgs> GetEFCoreArguments()
3944
{
40-
yield return new WriteBenchmarkArgs(TotalRecords: 200_000, BatchSize: 500);
45+
yield return new WriteBenchmarkArgs(TotalRecords: _totalRecordsForSetup, BatchSize: 500);
4146
}
4247

4348
[BenchmarkCategory("Write")]
4449
[Benchmark(Description = "EFCore - AddOrderItems")]
4550
[ArgumentsSource(nameof(GetEFCoreArguments))]
4651
public override async Task EFCore_AddOrderItems(WriteBenchmarkArgs args)
4752
{
48-
var batchArgs = _testOrderItems.Select(i => new Queries.AddOrderItemsArgs(
49-
i.OrderId, i.ProductId, i.Quantity, i.UnitPrice
50-
)).ToList();
51-
await Helpers.InsertInBatchesAsync(batchArgs, args.BatchSize, _efCoreImpl.AddOrderItems);
53+
await Helpers.InsertInBatchesAsync(_efCoreTestOrderItems[..args.TotalRecords], args.BatchSize, _efCoreImpl.AddOrderItems);
54+
var result = await _sqlcImpl.GetOrderItemsCountAsync();
55+
Assert.That(result?.Cnt, Is.EqualTo(args.TotalRecords));
5256
}
5357

5458
public static Func<Task> GetSeedMethod()
@@ -64,15 +68,10 @@ public static Func<Task> GetSeedMethod()
6468
[GlobalSetup]
6569
public async Task GlobalSetup()
6670
{
67-
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
68-
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
69-
70-
_testOrderItems = [.. Enumerable.Range(0, 5000).Select(i => new QuerySql.AddOrderItemsArgs(
71-
OrderId: orderIds[i % orderIds.Count].OrderId,
72-
ProductId: productIds[i % productIds.Count].ProductId,
73-
Quantity: Random.Shared.Next(1, 10),
74-
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
75-
))];
71+
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: OrderIdsCountForSetup));
72+
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: ProductIdsCountForSetup));
73+
_sqlcTestOrderItems = GetSqlcTestOrderItemsAsync(orderIds, productIds);
74+
_efCoreTestOrderItems = GetEFCoreTestOrderItems(orderIds, productIds);
7675
}
7776

7877
[IterationSetup]
@@ -82,6 +81,30 @@ public static void IterationSetup()
8281
Helpers.InvokeGarbageCollection();
8382
}
8483

84+
private static List<QuerySql.AddOrderItemsArgs> GetSqlcTestOrderItemsAsync(
85+
List<QuerySql.GetOrderIdsRow> orderIds,
86+
List<QuerySql.GetProductIdsRow> productIds)
87+
{
88+
return [.. Enumerable.Range(0, _totalRecordsForSetup).Select(i => new QuerySql.AddOrderItemsArgs(
89+
OrderId: orderIds[i % OrderIdsCountForSetup].OrderId,
90+
ProductId: productIds[i % ProductIdsCountForSetup].ProductId,
91+
Quantity: Random.Shared.Next(1, 10),
92+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
93+
))];
94+
}
95+
96+
private static List<Queries.AddOrderItemsArgs> GetEFCoreTestOrderItems(
97+
List<QuerySql.GetOrderIdsRow> orderIds,
98+
List<QuerySql.GetProductIdsRow> productIds)
99+
{
100+
return [.. Enumerable.Range(0, _totalRecordsForSetup).Select(i => new Queries.AddOrderItemsArgs(
101+
OrderId: orderIds[i % OrderIdsCountForSetup].OrderId,
102+
ProductId: productIds[i % ProductIdsCountForSetup].ProductId,
103+
Quantity: Random.Shared.Next(1, 10),
104+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
105+
))];
106+
}
107+
85108
private static async Task CleanupWriteTableAsync(string connectionString)
86109
{
87110
using var connection = new SqliteConnection(connectionString);

0 commit comments

Comments
 (0)