Skip to content

Commit 33d8149

Browse files
fix: have the seed database called from outside the benchmark setup to avoid multiple unnecessary seeding
1 parent 9195b82 commit 33d8149

File tree

11 files changed

+136
-131
lines changed

11 files changed

+136
-131
lines changed

benchmark/BenchmarkRunner/Benchmarks/BaseReadBenchmark.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private static int CalculateMaxConcurrency(int totalTasks, int maxConcurrency)
2323
maxConcurrency, totalTasks, Environment.ProcessorCount
2424
}.Min(x => x);
2525
}
26-
public static async Task<List<T>> ExecuteConcurrentlyAsync<T>(
26+
protected static async Task<List<T>> ExecuteConcurrentlyAsync<T>(
2727
int totalTasks,
2828
int maxConcurrency,
2929
Func<int, Task<List<T>>> taskFactory)
@@ -41,7 +41,9 @@ public static async Task<List<T>> ExecuteConcurrentlyAsync<T>(
4141
return [.. results.SelectMany(r => r)];
4242
}
4343

44-
private static async Task<List<T>> ExecuteWithThrottleAsync<T>(SemaphoreSlim semaphore, Func<Task<List<T>>> taskFactory)
44+
private static async Task<List<T>> ExecuteWithThrottleAsync<T>(
45+
SemaphoreSlim semaphore,
46+
Func<Task<List<T>>> taskFactory)
4547
{
4648
await semaphore.WaitAsync();
4749
try

benchmark/BenchmarkRunner/Benchmarks/MysqlReadBenchmark.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,6 @@ public class MysqlReadBenchmark : BaseReadBenchmark
2020
[Params(25, 100, 200)]
2121
public int ConcurrentQueries { get; set; }
2222

23-
[GlobalSetup]
24-
public async Task GlobalSetup()
25-
{
26-
await Helpers.InitializeOnceAsync(async () =>
27-
{
28-
await MysqlDatabaseHelper.CleanupDatabaseAsync(_connectionString);
29-
var seeder = new MysqlDatabaseSeeder(_connectionString);
30-
await seeder.SeedAsync(
31-
customerCount: CustomerCount, // selectivity: 1/500 of the table returned
32-
productsPerCategory: 150,
33-
ordersPerCustomer: 1000,
34-
itemsPerOrder: 20
35-
// 20 * 1000 = 20,000 possible rows returned
36-
);
37-
});
38-
}
39-
4023
[BenchmarkCategory("Read")]
4124
[Benchmark(Baseline = true, Description = "SQLC - GetCustomerOrders")]
4225
public override async Task Sqlc_GetCustomerOrders()
@@ -82,4 +65,19 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
8265
));
8366
});
8467
}
68+
69+
public static Func<Task> GetSeedMethod()
70+
{
71+
return async () =>
72+
{
73+
await MysqlDatabaseHelper.CleanupDatabaseAsync(_connectionString);
74+
var seeder = new MysqlDatabaseSeeder(_connectionString);
75+
await seeder.SeedAsync(
76+
customerCount: 500, // selectivity: 1/500 of the table returned
77+
productsPerCategory: 150,
78+
ordersPerCustomer: 1000,
79+
itemsPerOrder: 20 // 20 * 1000 = 20,000 possible rows returned
80+
);
81+
};
82+
}
8583
}

benchmark/BenchmarkRunner/Benchmarks/MysqlWriteBenchmark.cs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,15 @@ public class MysqlWriteBenchmark : BaseWriteBenchmark
3030
[GlobalSetup]
3131
public async Task GlobalSetup()
3232
{
33-
await Helpers.InitializeOnceAsync(async () =>
34-
{
35-
await MysqlDatabaseHelper.CleanupDatabaseAsync(_connectionString);
36-
var seeder = new MysqlDatabaseSeeder(_connectionString);
37-
await seeder.SeedAsync(
38-
customerCount: 10,
39-
productsPerCategory: 15,
40-
ordersPerCustomer: 300,
41-
itemsPerOrder: 0
42-
);
33+
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
34+
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
4335

44-
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
45-
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
46-
47-
_testOrderItems = [.. Enumerable.Range(0, TotalRecords).Select(i => new QuerySql.AddOrderItemsArgs(
48-
OrderId: orderIds[i % orderIds.Count].OrderId,
49-
ProductId: productIds[i % productIds.Count].ProductId,
50-
Quantity: Random.Shared.Next(1, 10),
51-
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
52-
))];
53-
});
36+
_testOrderItems = [.. Enumerable.Range(0, TotalRecords).Select(i => new QuerySql.AddOrderItemsArgs(
37+
OrderId: orderIds[i % orderIds.Count].OrderId,
38+
ProductId: productIds[i % productIds.Count].ProductId,
39+
Quantity: Random.Shared.Next(1, 10),
40+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
41+
))];
5442
}
5543

5644
[IterationSetup]
@@ -76,4 +64,19 @@ public override async Task EFCore_AddOrderItems()
7664
)).ToList();
7765
await Helpers.InsertInBatchesAsync(args, BatchSize, _efCoreImpl.AddOrderItems);
7866
}
67+
68+
public static Func<Task> GetSeedMethod()
69+
{
70+
return async () =>
71+
{
72+
await MysqlDatabaseHelper.CleanupDatabaseAsync(_connectionString);
73+
var seeder = new MysqlDatabaseSeeder(_connectionString);
74+
await seeder.SeedAsync(
75+
customerCount: 10,
76+
productsPerCategory: 15,
77+
ordersPerCustomer: 300,
78+
itemsPerOrder: 0
79+
);
80+
};
81+
}
7982
}

benchmark/BenchmarkRunner/Benchmarks/PostgresqlReadBenchmark.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,6 @@ public class PostgresqlReadBenchmark : BaseReadBenchmark
2020
[Params(25, 50, 100)]
2121
public int ConcurrentQueries { get; set; }
2222

23-
[GlobalSetup]
24-
public async Task GlobalSetup()
25-
{
26-
await Helpers.InitializeOnceAsync(async () =>
27-
{
28-
await PostgresqlDatabaseHelper.CleanupDatabaseAsync(_connectionString);
29-
var seeder = new PostgresqlDatabaseSeeder(_connectionString);
30-
await seeder.SeedAsync(
31-
customerCount: CustomerCount,
32-
productsPerCategory: 150, // with customer_id filter, this is 1/500 of the table returned
33-
ordersPerCustomer: 1000,
34-
itemsPerOrder: 20
35-
// 20 * 1000 = 20,000 possible rows returned
36-
);
37-
});
38-
}
39-
4023
[BenchmarkCategory("Read")]
4124
[Benchmark(Baseline = true, Description = "SQLC - GetCustomerOrders")]
4225
public override async Task Sqlc_GetCustomerOrders()
@@ -82,4 +65,19 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
8265
));
8366
});
8467
}
68+
69+
public static Func<Task> GetSeedMethod()
70+
{
71+
return async () =>
72+
{
73+
await PostgresqlDatabaseHelper.CleanupDatabaseAsync(_connectionString);
74+
var seeder = new PostgresqlDatabaseSeeder(_connectionString);
75+
await seeder.SeedAsync(
76+
customerCount: 500, // with customer_id filter, this is 1/500 of the table returned
77+
productsPerCategory: 150,
78+
ordersPerCustomer: 1000,
79+
itemsPerOrder: 20 // 20 * 1000 = 20,000 possible rows returned
80+
);
81+
};
82+
}
8583
}

benchmark/BenchmarkRunner/Benchmarks/PostgresqlWriteBenchmark.cs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,15 @@ public class PostgresqlWriteBenchmark : BaseWriteBenchmark
2828
[GlobalSetup]
2929
public async Task GlobalSetup()
3030
{
31-
await Helpers.InitializeOnceAsync(async () =>
32-
{
33-
PostgresqlDatabaseHelper.CleanupDatabaseAsync(_connectionString).GetAwaiter().GetResult();
34-
var seeder = new PostgresqlDatabaseSeeder(_connectionString);
35-
await seeder.SeedAsync(
36-
customerCount: 10,
37-
productsPerCategory: 15,
38-
ordersPerCustomer: 300,
39-
itemsPerOrder: 0
40-
);
31+
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
32+
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
4133

42-
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
43-
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
44-
45-
_testOrderItems = [.. Enumerable.Range(0, TotalRecords).Select(i => new QuerySql.AddOrderItemsArgs(
46-
OrderId: orderIds[i % orderIds.Count].OrderId,
47-
ProductId: productIds[i % productIds.Count].ProductId,
48-
Quantity: Random.Shared.Next(1, 10),
49-
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
50-
))];
51-
});
34+
_testOrderItems = [.. Enumerable.Range(0, TotalRecords).Select(i => new QuerySql.AddOrderItemsArgs(
35+
OrderId: orderIds[i % orderIds.Count].OrderId,
36+
ProductId: productIds[i % productIds.Count].ProductId,
37+
Quantity: Random.Shared.Next(1, 10),
38+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
39+
))];
5240
}
5341

5442
[IterationSetup]
@@ -74,4 +62,19 @@ public override async Task EFCore_AddOrderItems()
7462
)).ToList();
7563
await Helpers.InsertInBatchesAsync(args, BatchSize, _efCoreImpl.AddOrderItems);
7664
}
65+
66+
public static Func<Task> GetSeedMethod()
67+
{
68+
return async () =>
69+
{
70+
PostgresqlDatabaseHelper.CleanupDatabaseAsync(_connectionString).GetAwaiter().GetResult();
71+
var seeder = new PostgresqlDatabaseSeeder(_connectionString);
72+
await seeder.SeedAsync(
73+
customerCount: 10,
74+
productsPerCategory: 15,
75+
ordersPerCustomer: 300,
76+
itemsPerOrder: 0
77+
);
78+
};
79+
}
7780
}

benchmark/BenchmarkRunner/Benchmarks/SqliteReadBenchmark.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,6 @@ public class SqliteReadBenchmark : BaseReadBenchmark
2323
[Params(5, 25, 50)]
2424
public int ConcurrentQueries { get; set; }
2525

26-
[GlobalSetup]
27-
public async Task GlobalSetup()
28-
{
29-
await Helpers.InitializeOnceAsync(async () =>
30-
{
31-
SqliteDatabaseHelper.CleanupDatabase(_connectionString);
32-
await SqliteDatabaseHelper.InitializeDatabaseAsync(_connectionString);
33-
var seeder = new SqliteDatabaseSeeder(_connectionString);
34-
await seeder.SeedAsync(
35-
customerCount: CustomerCount, // with customer_id filter, this is 1/500 of the table returned
36-
productsPerCategory: 150,
37-
ordersPerCustomer: 500,
38-
itemsPerOrder: 10
39-
// 10 * 500 = 5,000 possible rows returned
40-
);
41-
});
42-
}
43-
4426
[BenchmarkCategory("Read")]
4527
[Benchmark(Baseline = true, Description = "SQLC - GetCustomerOrders")]
4628
public override async Task Sqlc_GetCustomerOrders()
@@ -86,4 +68,20 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
8668
));
8769
});
8870
}
71+
72+
public static Func<Task> GetSeedMethod()
73+
{
74+
return async () =>
75+
{
76+
SqliteDatabaseHelper.CleanupDatabase(_connectionString);
77+
await SqliteDatabaseHelper.InitializeDatabaseAsync(_connectionString);
78+
var seeder = new SqliteDatabaseSeeder(_connectionString);
79+
await seeder.SeedAsync(
80+
customerCount: 500, // with customer_id filter, this is 1/500 of the table returned
81+
productsPerCategory: 150,
82+
ordersPerCustomer: 500,
83+
itemsPerOrder: 10 // 10 * 500 = 5,000 possible rows returned
84+
);
85+
};
86+
}
8987
}

benchmark/BenchmarkRunner/Benchmarks/SqliteWriteBenchmark.cs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,15 @@ public class SqliteWriteBenchmark : BaseWriteBenchmark
3030
[GlobalSetup]
3131
public async Task GlobalSetup()
3232
{
33-
await Helpers.InitializeOnceAsync(async () =>
34-
{
35-
SqliteDatabaseHelper.CleanupDatabase(_connectionString);
36-
await SqliteDatabaseHelper.InitializeDatabaseAsync(_connectionString);
37-
var seeder = new SqliteDatabaseSeeder(_connectionString);
38-
await seeder.SeedAsync(
39-
customerCount: 10,
40-
productsPerCategory: 15,
41-
ordersPerCustomer: 300,
42-
itemsPerOrder: 0
43-
);
44-
45-
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
46-
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
33+
var orderIds = await _sqlcImpl.GetOrderIdsAsync(new QuerySql.GetOrderIdsArgs(Limit: 1000));
34+
var productIds = await _sqlcImpl.GetProductIdsAsync(new QuerySql.GetProductIdsArgs(Limit: 1000));
4735

48-
_testOrderItems = [.. Enumerable.Range(0, TotalRecords).Select(i => new QuerySql.AddOrderItemsArgs(
49-
OrderId: orderIds[i % orderIds.Count].OrderId,
50-
ProductId: productIds[i % productIds.Count].ProductId,
51-
Quantity: Random.Shared.Next(1, 10),
52-
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
53-
))];
54-
});
36+
_testOrderItems = [.. Enumerable.Range(0, TotalRecords).Select(i => new QuerySql.AddOrderItemsArgs(
37+
OrderId: orderIds[i % orderIds.Count].OrderId,
38+
ProductId: productIds[i % productIds.Count].ProductId,
39+
Quantity: Random.Shared.Next(1, 10),
40+
UnitPrice: (decimal)(Random.Shared.NextDouble() * 100 + 5)
41+
))];
5542
}
5643

5744
[IterationSetup]
@@ -77,4 +64,20 @@ public override async Task EFCore_AddOrderItems()
7764
)).ToList();
7865
await Helpers.InsertInBatchesAsync(args, BatchSize, _efCoreImpl.AddOrderItems);
7966
}
67+
68+
public static Func<Task> GetSeedMethod()
69+
{
70+
return async () =>
71+
{
72+
SqliteDatabaseHelper.CleanupDatabase(_connectionString);
73+
await SqliteDatabaseHelper.InitializeDatabaseAsync(_connectionString);
74+
var seeder = new SqliteDatabaseSeeder(_connectionString);
75+
await seeder.SeedAsync(
76+
customerCount: 10,
77+
productsPerCategory: 15,
78+
ordersPerCustomer: 300,
79+
itemsPerOrder: 0
80+
);
81+
};
82+
}
8083
}

benchmark/BenchmarkRunner/Runners/BaseBenchmarkRunner.cs renamed to benchmark/BenchmarkRunner/Runners/BaseRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
public abstract class BaseBenchmarkRunner
1+
public abstract class BaseRunner
22
{
33
public virtual string GetBasePath() => Path.Combine("benchmark", "BenchmarkDotNet.Artifacts");
44
public abstract Task RunReadsAsync();
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
using BenchmarkDotNet.Configs;
22
using BenchmarkRunner.Benchmarks;
33

4-
public sealed class MysqlRunner : BaseBenchmarkRunner
4+
public sealed class MysqlRunner : BaseRunner
55
{
66
public override string GetBasePath() => Path.Combine(base.GetBasePath(), "mysql");
77

8-
public override Task RunReadsAsync()
8+
public override async Task RunReadsAsync()
99
{
10+
await MysqlReadBenchmark.GetSeedMethod().Invoke();
1011
var path = Path.Combine(GetBasePath(), "reads");
1112
BenchmarkDotNet.Running.BenchmarkRunner.Run<MysqlReadBenchmark>(
1213
DefaultConfig.Instance.WithArtifactsPath(path)
1314
);
14-
return Task.CompletedTask;
1515
}
1616

17-
public override Task RunWritesAsync()
17+
public override async Task RunWritesAsync()
1818
{
19+
await MysqlWriteBenchmark.GetSeedMethod().Invoke();
1920
var path = Path.Combine(GetBasePath(), "writes");
2021
BenchmarkDotNet.Running.BenchmarkRunner.Run<MysqlWriteBenchmark>(
2122
DefaultConfig.Instance.WithArtifactsPath(path)
2223
);
23-
return Task.CompletedTask;
2424
}
2525
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
using BenchmarkDotNet.Configs;
22
using BenchmarkRunner.Benchmarks;
33

4-
public sealed class PostgresqlRunner : BaseBenchmarkRunner
4+
public sealed class PostgresqlRunner : BaseRunner
55
{
66
public override string GetBasePath() => Path.Combine(base.GetBasePath(), "postgresql");
77

8-
public override Task RunReadsAsync()
8+
public override async Task RunReadsAsync()
99
{
10+
await PostgresqlReadBenchmark.GetSeedMethod().Invoke();
1011
var path = Path.Combine(GetBasePath(), "reads");
1112
BenchmarkDotNet.Running.BenchmarkRunner.Run<PostgresqlReadBenchmark>(
1213
DefaultConfig.Instance.WithArtifactsPath(path)
1314
);
14-
return Task.CompletedTask;
1515
}
1616

17-
public override Task RunWritesAsync()
17+
public override async Task RunWritesAsync()
1818
{
19+
await PostgresqlWriteBenchmark.GetSeedMethod().Invoke();
1920
var path = Path.Combine(GetBasePath(), "writes");
2021
BenchmarkDotNet.Running.BenchmarkRunner.Run<PostgresqlWriteBenchmark>(
2122
DefaultConfig.Instance.WithArtifactsPath(path)
2223
);
23-
return Task.CompletedTask;
2424
}
2525
}

0 commit comments

Comments
 (0)