diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs index 9f83617dc..98fb1bd9b 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs @@ -20,7 +20,7 @@ private readonly MemoryCache _cache = new(new MemoryCacheOptions { ExpirationScanFrequency = TimeSpan.FromMinutes(60) }); #if NET7_0_OR_GREATER - private readonly NpgsqlDataSource _dataSource; + private readonly NpgsqlDataSource _dataSource, _updateDataSource, _readOnlyDataSource; #else private readonly string _connectionString; #endif @@ -30,6 +30,15 @@ public RawDb(ConcurrentRandom random, AppSettings appSettings) _random = random; #if NET7_0_OR_GREATER _dataSource = NpgsqlDataSource.Create(appSettings.ConnectionString); + + // For the update benchmark, we use two different connection pools for read/update, to avoid head-of-line + // perf issues. + var dataSourceBuilder = new NpgsqlDataSourceBuilder(appSettings.ConnectionString); + + dataSourceBuilder.ConnectionStringBuilder.MaxPoolSize = 18; + _readOnlyDataSource = dataSourceBuilder.Build(); + dataSourceBuilder.ConnectionStringBuilder.MaxPoolSize = 9; + _updateDataSource = dataSourceBuilder.Build(); #else _connectionString = appSettings.ConnectionString; #endif @@ -170,14 +179,12 @@ public async Task LoadMultipleQueriesRows(int count) } #endif +#if NET7_0_OR_GREATER public async Task LoadMultipleUpdatesRows(int count) { var results = new World[count]; - using var connection = CreateConnection(); - await connection.OpenAsync(); - -#if NET7_0_OR_GREATER + using (var connection = await _readOnlyDataSource.OpenConnectionAsync()) using (var batch = new NpgsqlBatch(connection)) { // Inserts a PG Sync message between each statement in the batch, required for compliance with @@ -203,7 +210,33 @@ public async Task LoadMultipleUpdatesRows(int count) await reader.NextResultAsync(); } } + + using (var connection = await _updateDataSource.OpenConnectionAsync()) + using (var updateCmd = new NpgsqlCommand(BatchUpdateString.Query(count), connection)) + { + for (var i = 0; i < results.Length; i++) + { + var randomNumber = _random.Next(1, 10001); + + updateCmd.Parameters.Add(new NpgsqlParameter { TypedValue = results[i].Id }); + updateCmd.Parameters.Add(new NpgsqlParameter { TypedValue = randomNumber }); + + results[i].RandomNumber = randomNumber; + } + + await updateCmd.ExecuteNonQueryAsync(); + } + + return results; + } #else + public async Task LoadMultipleUpdatesRows(int count) + { + var results = new World[count]; + + using var connection = CreateConnection(); + await connection.OpenAsync(); + var (queryCmd, queryParameter) = CreateReadCommand(connection); using (queryCmd) { @@ -213,7 +246,6 @@ public async Task LoadMultipleUpdatesRows(int count) queryParameter.TypedValue = _random.Next(1, 10001); } } -#endif using (var updateCmd = new NpgsqlCommand(BatchUpdateString.Query(count), connection)) { @@ -232,6 +264,7 @@ public async Task LoadMultipleUpdatesRows(int count) return results; } +#endif public async Task> LoadFortunesRows() {