Эх сурвалжийг харах

Merge pull request #17 from TechEmpower/master

aa
三刀 4 жил өмнө
parent
commit
4afb6b459b
100 өөрчлөгдсөн 1888 нэмэгдсэн , 558 устгасан
  1. 31 0
      frameworks/CSharp/aspnetcore/Benchmarks.sln
  2. 4 5
      frameworks/CSharp/aspnetcore/Benchmarks/Benchmarks.csproj
  3. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesDapperMiddleware.cs
  4. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesEfMiddleware.cs
  5. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesRawMiddleware.cs
  6. 3 8
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesDapperMiddleware.cs
  7. 3 8
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesEfMiddleware.cs
  8. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesRawMiddleware.cs
  9. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryDapperMiddleware.cs
  10. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryEfMiddleware.cs
  11. 3 7
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryRawMiddleware.cs
  12. 5 10
      frameworks/CSharp/aspnetcore/Benchmarks/Startup.cs
  13. 1 1
      frameworks/CSharp/aspnetcore/Benchmarks/appsettings.postgresql.json
  14. 1 1
      frameworks/CSharp/aspnetcore/Benchmarks/appsettings.postgresql.updates.json
  15. 1 1
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.Caching.cs
  16. 1 41
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs
  17. 2 3
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.Json.cs
  18. 4 3
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.MultipleQueries.cs
  19. 1 1
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.SingleQuery.cs
  20. 1 1
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.Updates.cs
  21. 10 8
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.cs
  22. 0 2
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkConfigurationHelpers.cs
  23. 1 4
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/Data/CachedWorld.cs
  24. 6 9
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/Data/Providers/RawDbMySqlConnector.cs
  25. 7 10
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/Data/Providers/RawDbNpgsql.cs
  26. 3 5
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/PlatformBenchmarks.csproj
  27. 17 3
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/Program.cs
  28. 1 1
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/appsettings.postgresql.json
  29. 1 1
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/appsettings.postgresql.updates.json
  30. 8 2
      frameworks/CSharp/aspnetcore/aspcore-ado-my.dockerfile
  31. 8 2
      frameworks/CSharp/aspnetcore/aspcore-ado-pg-up.dockerfile
  32. 8 2
      frameworks/CSharp/aspnetcore/aspcore-ado-pg.dockerfile
  33. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-ado-my.dockerfile
  34. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-ado-pg-up.dockerfile
  35. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-ado-pg.dockerfile
  36. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-dap-my.dockerfile
  37. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-dap-pg-up.dockerfile
  38. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-dap-pg.dockerfile
  39. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc-ef-pg.dockerfile
  40. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mvc.dockerfile
  41. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-ado-my.dockerfile
  42. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-ado-pg-up.dockerfile
  43. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-ado-pg.dockerfile
  44. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-dap-my.dockerfile
  45. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-dap-pg-up.dockerfile
  46. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-dap-pg.dockerfile
  47. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-ef-pg.dockerfile
  48. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw-json.dockerfile
  49. 8 2
      frameworks/CSharp/aspnetcore/aspcore-mw.dockerfile
  50. 8 2
      frameworks/CSharp/aspnetcore/aspcore.dockerfile
  51. 203 0
      frameworks/CSharp/aspnetcore/te.benchmarks.yml
  52. 2 0
      frameworks/Elixir/phoenix/config/prod.exs
  53. 1 8
      frameworks/Elixir/phoenix/lib/hello_web.ex
  54. 33 30
      frameworks/Elixir/phoenix/lib/hello_web/controllers/page_controller.ex
  55. 1 2
      frameworks/Elixir/phoenix/mix.exs
  56. 6 10
      frameworks/Elixir/phoenix/mix.lock
  57. 45 0
      frameworks/Java/inverno/README.md
  58. 47 0
      frameworks/Java/inverno/benchmark_config.json
  59. 11 0
      frameworks/Java/inverno/inverno-postgres.dockerfile
  60. 9 0
      frameworks/Java/inverno/inverno.dockerfile
  61. 125 0
      frameworks/Java/inverno/pom.xml
  62. 99 0
      frameworks/Java/inverno/src/jmods/io.vertx.core/module-info.java
  63. 38 0
      frameworks/Java/inverno/src/jmods/r2dbc.postgresql/module-info.java
  64. 36 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/AppConfiguration.java
  65. 21 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/Main.java
  66. 306 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/Handler.java
  67. 67 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/PoolSqlClientReactorScope.java
  68. 67 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/PooledClientSqlClientReactorScope.java
  69. 25 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/model/Fortune.java
  70. 14 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/model/Message.java
  71. 33 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/model/World.java
  72. 30 0
      frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/templates/FortunesTemplate.irt
  73. 28 0
      frameworks/Java/inverno/src/main/java/module-info.java
  74. 16 0
      frameworks/Java/inverno/src/main/resources/configuration.cprops
  75. 4 4
      frameworks/Java/officefloor/src/woof_benchmark_sqlclient/src/main/java/net/officefloor/benchmark/SqlClientOfficeFloorMain.java
  76. 25 3
      frameworks/Java/redkale/benchmark_config.json
  77. 3 8
      frameworks/Java/redkale/conf/application.xml
  78. 21 0
      frameworks/Java/redkale/conf/persistence-mongodb.xml
  79. 0 2
      frameworks/Java/redkale/conf/persistence.xml
  80. 19 3
      frameworks/Java/redkale/config.toml
  81. 5 35
      frameworks/Java/redkale/pom-mongodb.xml
  82. 0 61
      frameworks/Java/redkale/pom.xml
  83. 25 0
      frameworks/Java/redkale/redkale-mongodb.dockerfile
  84. 1 1
      frameworks/Java/redkale/redkale-native.dockerfile
  85. 26 28
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/BenchmarkService.java
  86. 7 7
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/CachedWorld.java
  87. 63 0
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/FortuneRender.java
  88. 0 45
      frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/RedRandom.java
  89. 0 9
      frameworks/Java/redkale/src/main/templates/org/redkalex/benchmark/FortunesTemplate.rocker.html
  90. 2 2
      frameworks/Java/vertx/README.md
  91. 13 7
      frameworks/Java/vertx/pom.xml
  92. 1 2
      frameworks/Java/vertx/src/main/conf/config.json
  93. 108 68
      frameworks/Java/vertx/src/main/java/vertx/App.java
  94. 3 0
      frameworks/Java/vertx/vertx-postgres.dockerfile
  95. 1 1
      frameworks/Java/vertx/vertx.dockerfile
  96. 1 1
      frameworks/Java/wildfly-ee/wildfly-ee.dockerfile
  97. 1 1
      frameworks/JavaScript/express/README.md
  98. 1 1
      frameworks/JavaScript/express/express-mongodb.dockerfile
  99. 1 1
      frameworks/JavaScript/express/express-mysql.dockerfile
  100. 1 1
      frameworks/JavaScript/express/express-postgres.dockerfile

+ 31 - 0
frameworks/CSharp/aspnetcore/Benchmarks.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31717.71
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformBenchmarks", "PlatformBenchmarks\PlatformBenchmarks.csproj", "{047A5FF4-56BB-4BEF-9DCF-9B6051365423}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{C65B0C4A-B242-4A03-AC80-4B1DC6C1DF57}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{047A5FF4-56BB-4BEF-9DCF-9B6051365423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{047A5FF4-56BB-4BEF-9DCF-9B6051365423}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{047A5FF4-56BB-4BEF-9DCF-9B6051365423}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{047A5FF4-56BB-4BEF-9DCF-9B6051365423}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C65B0C4A-B242-4A03-AC80-4B1DC6C1DF57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C65B0C4A-B242-4A03-AC80-4B1DC6C1DF57}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C65B0C4A-B242-4A03-AC80-4B1DC6C1DF57}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C65B0C4A-B242-4A03-AC80-4B1DC6C1DF57}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {69C5D834-F31B-4F07-97EC-E4DD5AF417DE}
+	EndGlobalSection
+EndGlobal

+ 4 - 5
frameworks/CSharp/aspnetcore/Benchmarks/Benchmarks.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
   <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
     <OutputType>Exe</OutputType>
   </PropertyGroup>
 
@@ -12,11 +12,10 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.5" />
-    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.5" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0-rc.1.21452.10" />
 
     <PackageReference Include="Dapper" Version="2.0.90" />
-    <PackageReference Include="MySqlConnector" Version="1.3.2" />
-    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
+    <PackageReference Include="MySqlConnector" Version="1.3.12" />
+    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.0-rc.1" />
   </ItemGroup>
 </Project>

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesDapperMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class MultipleQueriesDapperMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiQueryDapper));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -37,7 +33,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<DapperDb>();
                 var rows = await db.LoadMultipleQueriesRows(count);
 
-                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+                var result = JsonSerializer.Serialize(rows, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesEfMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class MultipleQueriesEfMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiQueryEf));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -37,7 +33,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<EfDb>();
                 var rows = await db.LoadMultipleQueriesRows(count);
 
-                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+                var result = JsonSerializer.Serialize(rows, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesRawMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class MultipleQueriesRawMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiQueryRaw));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -37,7 +33,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<RawDb>();
                 var rows = await db.LoadMultipleQueriesRows(count);
 
-                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+                var result = JsonSerializer.Serialize(rows, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 8
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesDapperMiddleware.cs

@@ -2,25 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class MultipleUpdatesDapperMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiUpdateDapper));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
-
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
         private readonly RequestDelegate _next;
 
         public MultipleUpdatesDapperMiddleware(RequestDelegate next)
@@ -37,7 +32,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<DapperDb>();
                 var rows = await db.LoadMultipleUpdatesRows(count);
 
-                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+                var result = JsonSerializer.Serialize(rows, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 8
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesEfMiddleware.cs

@@ -2,25 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class MultipleUpdatesEfMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiUpdateEf));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
-
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
         private readonly RequestDelegate _next;
 
         public MultipleUpdatesEfMiddleware(RequestDelegate next)
@@ -37,7 +32,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<EfDb>();
                 var rows = await db.LoadMultipleUpdatesRows(count);
 
-                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+                var result = JsonSerializer.Serialize(rows, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesRawMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class MultipleUpdatesRawMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiUpdateRaw));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -37,7 +33,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<RawDb>();
                 var rows = await db.LoadMultipleUpdatesRows(count);
 
-                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+                var result = JsonSerializer.Serialize(rows, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryDapperMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class SingleQueryDapperMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbSingleQueryDapper));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -35,7 +31,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<DapperDb>();
                 var row = await db.LoadSingleQueryRow();
 
-                var result = JsonConvert.SerializeObject(row, _jsonSettings);
+                var result = JsonSerializer.Serialize(row, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryEfMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class SingleQueryEfMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbSingleQueryEf));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -34,7 +30,7 @@ namespace Benchmarks.Middleware
             {
                 var db = httpContext.RequestServices.GetService<EfDb>();
                 var row = await db.LoadSingleQueryRow();
-                var result = JsonConvert.SerializeObject(row, _jsonSettings);
+                var result = JsonSerializer.Serialize(row, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 3 - 7
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryRawMiddleware.cs

@@ -2,24 +2,20 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Text.Json;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
 
 namespace Benchmarks.Middleware
 {
     public class SingleQueryRawMiddleware
     {
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbSingleQueryRaw));
-        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
-        {
-            ContractResolver = new CamelCasePropertyNamesContractResolver()
-        };
+        private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
 
         private readonly RequestDelegate _next;
 
@@ -35,7 +31,7 @@ namespace Benchmarks.Middleware
                 var db = httpContext.RequestServices.GetService<RawDb>();
                 var row = await db.LoadSingleQueryRow();
 
-                var result = JsonConvert.SerializeObject(row, _jsonSettings);
+                var result = JsonSerializer.Serialize(row, _serializerOptions);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
                 httpContext.Response.ContentType = "application/json";

+ 5 - 10
frameworks/CSharp/aspnetcore/Benchmarks/Startup.cs

@@ -1,22 +1,20 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-using System;
-using System.Data.Common;
-using System.Data.SqlClient;
-using System.Text.Encodings.Web;
-using System.Text.Unicode;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Benchmarks.Middleware;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Mvc;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using MySqlConnector;
 using Npgsql;
+using System;
+using System.Data.Common;
+using System.Text.Encodings.Web;
+using System.Text.Unicode;
 
 namespace Benchmarks
 {
@@ -106,10 +104,7 @@ namespace Benchmarks
 
             if (Scenarios.Any("Mvc"))
             {
-                var mvcBuilder = services
-                    .AddMvcCore()
-                    .SetCompatibilityVersion(CompatibilityVersion.Latest)
-                    ;
+                var mvcBuilder = services.AddMvcCore();
 
                 if (Scenarios.MvcViews || Scenarios.Any("MvcDbFortunes"))
                 {

+ 1 - 1
frameworks/CSharp/aspnetcore/Benchmarks/appsettings.postgresql.json

@@ -1,4 +1,4 @@
 {
-  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000",
+  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Buffer Threshold Bytes=1000",
   "Database": "postgresql"
 }

+ 1 - 1
frameworks/CSharp/aspnetcore/Benchmarks/appsettings.postgresql.updates.json

@@ -1,4 +1,4 @@
 {
-  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000",
+  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Buffer Threshold Bytes=1000",
   "Database": "postgresql"
 }

+ 1 - 1
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.Caching.cs

@@ -12,7 +12,7 @@ namespace PlatformBenchmarks
     {
         private async Task Caching(PipeWriter pipeWriter, int count)
         {
-            OutputMultipleQueries(pipeWriter, await Db.LoadCachedQueries(count));
+            OutputMultipleQueries(pipeWriter, await Db.LoadCachedQueries(count), SerializerContext.CachedWorldArray);
         }
     }
 }

+ 1 - 41
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs

@@ -112,21 +112,10 @@ namespace PlatformBenchmarks
 
             if (state == State.StartLine)
             {
-#if NET5_0
                 if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
                 {
                     state = State.Headers;
                 }
-#else
-                var unconsumedSequence = reader.Sequence.Slice(reader.Position);
-                if (Parser.ParseRequestLine(new ParsingAdapter(this), unconsumedSequence, out var consumed, out _))
-                {
-                    state = State.Headers;
-
-                    var parsedLength = unconsumedSequence.Slice(reader.Position, consumed).Length;
-                    reader.Advance(parsedLength);
-                }
-#endif
             }
 
             if (state == State.Headers)
@@ -197,21 +186,10 @@ namespace PlatformBenchmarks
 
             if (state == State.StartLine)
             {
-#if NET5_0
                 if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
                 {
                     state = State.Headers;
                 }
-#else
-                var unconsumedSequence = reader.Sequence.Slice(reader.Position);
-                if (Parser.ParseRequestLine(new ParsingAdapter(this), unconsumedSequence, out var consumed, out _))
-                {
-                    state = State.Headers;
-
-                    var parsedLength = unconsumedSequence.Slice(reader.Position, consumed).Length;
-                    reader.Advance(parsedLength);
-                }
-#endif
             }
 
             if (state == State.Headers)
@@ -246,8 +224,6 @@ namespace PlatformBenchmarks
         }
 #endif
 
-#if NET5_0
-
         public void OnStaticIndexedHeader(int index)
         {
         }
@@ -259,17 +235,10 @@ namespace PlatformBenchmarks
         public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
         {
         }
+
         public void OnHeadersComplete(bool endStream)
         {
         }
-#else
-        public void OnHeader(Span<byte> name, Span<byte> value)
-        {
-        }
-        public void OnHeadersComplete()
-        {
-        }
-#endif
 
         private static void ThrowUnexpectedEndOfData()
         {
@@ -311,7 +280,6 @@ namespace PlatformBenchmarks
             public ParsingAdapter(BenchmarkApplication requestHandler)
                 => RequestHandler = requestHandler;
 
-#if NET5_0
             public void OnStaticIndexedHeader(int index) 
                 => RequestHandler.OnStaticIndexedHeader(index);
 
@@ -326,14 +294,6 @@ namespace PlatformBenchmarks
 
             public void OnStartLine(HttpVersionAndMethod versionAndMethod, TargetOffsetPathLength targetPath, Span<byte> startLine)
                 => RequestHandler.OnStartLine(versionAndMethod, targetPath, startLine);
-#else
-            public void OnHeader(Span<byte> name, Span<byte> value)
-                => RequestHandler.OnHeader(name, value);
-            public void OnHeadersComplete()
-                => RequestHandler.OnHeadersComplete();
-            public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
-                => RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
-#endif
         }
     }
 }

+ 2 - 3
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.Json.cs

@@ -1,7 +1,6 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-using System;
 using System.Buffers;
 using System.Text.Json;
 
@@ -9,7 +8,7 @@ namespace PlatformBenchmarks
 {
     public partial class BenchmarkApplication
     {
-        private readonly static uint _jsonPayloadSize = (uint)JsonSerializer.SerializeToUtf8Bytes(new JsonMessage { message = "Hello, World!" }, SerializerOptions).Length;
+        private readonly static uint _jsonPayloadSize = (uint)JsonSerializer.SerializeToUtf8Bytes(new JsonMessage { message = "Hello, World!" }, SerializerContext.JsonMessage).Length;
 
         private readonly static AsciiString _jsonPreamble =
             _http11OK +
@@ -30,7 +29,7 @@ namespace PlatformBenchmarks
             utf8JsonWriter.Reset(bodyWriter);
 
             // Body
-            JsonSerializer.Serialize<JsonMessage>(utf8JsonWriter, new JsonMessage { message = "Hello, World!" }, SerializerOptions);
+            JsonSerializer.Serialize(utf8JsonWriter, new JsonMessage { message = "Hello, World!" }, SerializerContext.JsonMessage);        
         }
     }
 }

+ 4 - 3
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.MultipleQueries.cs

@@ -5,6 +5,7 @@
 
 using System.IO.Pipelines;
 using System.Text.Json;
+using System.Text.Json.Serialization.Metadata;
 using System.Threading.Tasks;
 
 namespace PlatformBenchmarks
@@ -13,10 +14,10 @@ namespace PlatformBenchmarks
     {
         private async Task MultipleQueries(PipeWriter pipeWriter, int count)
         {
-            OutputMultipleQueries(pipeWriter, await Db.LoadMultipleQueriesRows(count));
+            OutputMultipleQueries(pipeWriter, await Db.LoadMultipleQueriesRows(count), SerializerContext.WorldArray);
         }
 
-        private static void OutputMultipleQueries(PipeWriter pipeWriter, World[] rows)
+        private static void OutputMultipleQueries<TWorld>(PipeWriter pipeWriter, TWorld[] rows, JsonTypeInfo<TWorld[]> jsonTypeInfo)
         {
             var writer = GetWriter(pipeWriter, sizeHint: 160 * rows.Length); // in reality it's 152 for one
 
@@ -34,7 +35,7 @@ namespace PlatformBenchmarks
             utf8JsonWriter.Reset(pipeWriter);
 
             // Body
-            JsonSerializer.Serialize<World[]>(utf8JsonWriter, rows, SerializerOptions);
+            JsonSerializer.Serialize<TWorld[]>(utf8JsonWriter, rows, jsonTypeInfo);
 
             // Content-Length
             lengthWriter.WriteNumeric((uint)utf8JsonWriter.BytesCommitted);

+ 1 - 1
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.SingleQuery.cs

@@ -34,7 +34,7 @@ namespace PlatformBenchmarks
             utf8JsonWriter.Reset(pipeWriter);
 
             // Body
-            JsonSerializer.Serialize<World>(utf8JsonWriter, row, SerializerOptions);
+            JsonSerializer.Serialize(utf8JsonWriter, row, SerializerContext.World);
 
             // Content-Length
             lengthWriter.WriteNumeric((uint)utf8JsonWriter.BytesCommitted);

+ 1 - 1
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.Updates.cs

@@ -34,7 +34,7 @@ namespace PlatformBenchmarks
             utf8JsonWriter.Reset(pipeWriter);
 
             // Body
-            JsonSerializer.Serialize<World[]>(utf8JsonWriter, rows, SerializerOptions);
+            JsonSerializer.Serialize( utf8JsonWriter, rows, SerializerContext.WorldArray);
 
             // Content-Length
             lengthWriter.WriteNumeric((uint)utf8JsonWriter.BytesCommitted);

+ 10 - 8
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkApplication.cs

@@ -5,6 +5,7 @@ using System;
 using System.Buffers.Text;
 using System.IO.Pipelines;
 using System.Text.Json;
+using System.Text.Json.Serialization;
 using System.Threading.Tasks;
 
 using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
@@ -35,7 +36,15 @@ namespace PlatformBenchmarks
 
         private readonly static AsciiString _plainTextBody = "Hello, World!";
 
-        private static readonly JsonSerializerOptions SerializerOptions = new JsonSerializerOptions();
+        private static readonly JsonContext SerializerContext = JsonContext.Default;
+
+        [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
+        [JsonSerializable(typeof(JsonMessage))]
+        [JsonSerializable(typeof(CachedWorld[]))]
+        [JsonSerializable(typeof(World[]))]
+        private sealed partial class JsonContext : JsonSerializerContext
+        {
+        }
 
         private readonly static AsciiString _fortunesTableStart = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
         private readonly static AsciiString _fortunesRowStart = "<tr><td>";
@@ -65,17 +74,10 @@ namespace PlatformBenchmarks
         private RequestType _requestType;
         private int _queries;
 
-#if NET5_0
         public void OnStartLine(HttpVersionAndMethod versionAndMethod, TargetOffsetPathLength targetPath, Span<byte> startLine)
         {
             _requestType = versionAndMethod.Method == HttpMethod.Get ? GetRequestType(startLine.Slice(targetPath.Offset, targetPath.Length), ref _queries) : RequestType.NotRecognized;
         }
-#else
-        public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
-        {
-            _requestType = method == HttpMethod.Get ? GetRequestType(path, ref _queries) : RequestType.NotRecognized;
-        }
-#endif
 
         private RequestType GetRequestType(ReadOnlySpan<byte> path, ref int queries)
         {

+ 0 - 2
frameworks/CSharp/aspnetcore/PlatformBenchmarks/BenchmarkConfigurationHelpers.cs

@@ -24,7 +24,6 @@ namespace PlatformBenchmarks
                     options.IOQueueCount = threadCount;
                 }
 
-#if NET5_0
                 options.WaitForDataBeforeAllocatingBuffer = false;
                 if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                 {
@@ -32,7 +31,6 @@ namespace PlatformBenchmarks
                 }
 
                 Console.WriteLine($"Options: WaitForData={options.WaitForDataBeforeAllocatingBuffer}, PreferInlineScheduling={options.UnsafePreferInlineScheduling}, IOQueue={options.IOQueueCount}");
-#endif
             });
 
             return builder;

+ 1 - 4
frameworks/CSharp/aspnetcore/PlatformBenchmarks/Data/CachedWorld.cs

@@ -1,17 +1,14 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
-using System.Runtime.InteropServices;
-
 namespace PlatformBenchmarks
 {
-    public class CachedWorld
+    public sealed class CachedWorld
     {
         public int Id { get; set; }
 
         public int RandomNumber { get; set; }
 
-        public static implicit operator World(CachedWorld world) => new World { Id = world.Id, RandomNumber = world.RandomNumber };
         public static implicit operator CachedWorld(World world) => new CachedWorld { Id = world.Id, RandomNumber = world.RandomNumber };
     }
 }

+ 6 - 9
frameworks/CSharp/aspnetcore/PlatformBenchmarks/Data/Providers/RawDbMySqlConnector.cs

@@ -67,9 +67,9 @@ namespace PlatformBenchmarks
             return result;
         }
 
-        public Task<World[]> LoadCachedQueries(int count)
+        public Task<CachedWorld[]> LoadCachedQueries(int count)
         {
-            var result = new World[count];
+            var result = new CachedWorld[count];
             var cacheKeys = _cacheKeys;
             var cache = _cache;
             var random = _random;
@@ -77,11 +77,9 @@ namespace PlatformBenchmarks
             {
                 var id = random.Next(1, 10001);
                 var key = cacheKeys[id];
-                var data = cache.Get<CachedWorld>(key);
-
-                if (data != null)
+                if (cache.TryGetValue(key, out object cached))
                 {
-                    result[i] = data;
+                    result[i] = (CachedWorld)cached;
                 }
                 else
                 {
@@ -91,7 +89,7 @@ namespace PlatformBenchmarks
 
             return Task.FromResult(result);
 
-            static async Task<World[]> LoadUncachedQueries(int id, int i, int count, RawDb rawdb, World[] result)
+            static async Task<CachedWorld[]> LoadUncachedQueries(int id, int i, int count, RawDb rawdb, CachedWorld[] result)
             {
                 using (var db = new MySqlConnection(rawdb._connectionString))
                 {
@@ -112,8 +110,7 @@ namespace PlatformBenchmarks
 
                         for (; i < result.Length; i++)
                         {
-                            var data = await rawdb._cache.GetOrCreateAsync<CachedWorld>(key, create);
-                            result[i] = data;
+                            result[i] = await rawdb._cache.GetOrCreateAsync<CachedWorld>(key, create);
 
                             id = rawdb._random.Next(1, 10001);
                             idParameter.Value = id;

+ 7 - 10
frameworks/CSharp/aspnetcore/PlatformBenchmarks/Data/Providers/RawDbNpgsql.cs

@@ -67,9 +67,9 @@ namespace PlatformBenchmarks
             return result;
         }
 
-        public Task<World[]> LoadCachedQueries(int count)
+        public Task<CachedWorld[]> LoadCachedQueries(int count)
         {
-            var result = new World[count];
+            var result = new CachedWorld[count];
             var cacheKeys = _cacheKeys;
             var cache = _cache;
             var random = _random;
@@ -77,11 +77,9 @@ namespace PlatformBenchmarks
             {
                 var id = random.Next(1, 10001);
                 var key = cacheKeys[id];
-                var data = cache.Get<CachedWorld>(key);
-
-                if (data != null)
+                if (cache.TryGetValue(key, out object cached))
                 {
-                    result[i] = data;
+                    result[i] = (CachedWorld)cached;
                 }
                 else
                 {
@@ -91,7 +89,7 @@ namespace PlatformBenchmarks
 
             return Task.FromResult(result);
 
-            static async Task<World[]> LoadUncachedQueries(int id, int i, int count, RawDb rawdb, World[] result)
+            static async Task<CachedWorld[]> LoadUncachedQueries(int id, int i, int count, RawDb rawdb, CachedWorld[] result)
             {
                 using (var db = new NpgsqlConnection(rawdb._connectionString))
                 {
@@ -112,8 +110,7 @@ namespace PlatformBenchmarks
 
                         for (; i < result.Length; i++)
                         {
-                            var data = await rawdb._cache.GetOrCreateAsync<CachedWorld>(key, create);
-                            result[i] = data;
+                            result[i] = await rawdb._cache.GetOrCreateAsync<CachedWorld>(key, create);
 
                             id = rawdb._random.Next(1, 10001);
                             idParameter.TypedValue = id;
@@ -190,7 +187,7 @@ namespace PlatformBenchmarks
 
         public async Task<List<Fortune>> LoadFortunesRows()
         {
-            var result = new List<Fortune>();
+            var result = new List<Fortune>(20);
 
             using (var db = new NpgsqlConnection(_connectionString))
             {

+ 3 - 5
frameworks/CSharp/aspnetcore/PlatformBenchmarks/PlatformBenchmarks.csproj

@@ -1,7 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
-
   <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
     <OutputType>Exe</OutputType>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
@@ -13,12 +12,11 @@
   </PropertyGroup>
   
   <ItemGroup>
-    <PackageReference Condition=" '$(DatabaseProvider)' == 'Npgsql' " Include="Npgsql" Version="5.0.4" />
-    <PackageReference Condition=" '$(DatabaseProvider)' == 'MySqlConnector' " Include="MySqlConnector" Version="1.3.8" />
+    <PackageReference Condition=" '$(DatabaseProvider)' == 'Npgsql' " Include="Npgsql" Version="6.0.0-rc.1" />
+    <PackageReference Condition=" '$(DatabaseProvider)' == 'MySqlConnector' " Include="MySqlConnector" Version="1.3.12" />
   </ItemGroup>
 
   <ItemGroup>
       <None Include="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
   </ItemGroup>
-
 </Project>

+ 17 - 3
frameworks/CSharp/aspnetcore/PlatformBenchmarks/Program.cs

@@ -2,6 +2,8 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Net;
+using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.Configuration;
@@ -62,7 +64,7 @@ namespace PlatformBenchmarks
             }
 #endif
 
-            var host = new WebHostBuilder()
+            var hostBuilder = new WebHostBuilder()
                 .UseBenchmarksConfiguration(config)
                 .UseKestrel((context, options) =>
                 {
@@ -73,8 +75,20 @@ namespace PlatformBenchmarks
                         builder.UseHttpApplication<BenchmarkApplication>();
                     });
                 })
-                .UseStartup<Startup>()
-                .Build();
+                .UseStartup<Startup>();
+
+            hostBuilder.UseSockets(options =>
+            {
+                options.WaitForDataBeforeAllocatingBuffer = false;
+
+                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+                {
+                    options.UnsafePreferInlineScheduling = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS") == "1";
+                }
+            });
+
+
+            var host = hostBuilder.Build();
 
             return host;
         }

+ 1 - 1
frameworks/CSharp/aspnetcore/PlatformBenchmarks/appsettings.postgresql.json

@@ -1,4 +1,4 @@
 {
-  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000",
+  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Buffer Threshold Bytes=1000",
   "Database": "postgresql"
 }

+ 1 - 1
frameworks/CSharp/aspnetcore/PlatformBenchmarks/appsettings.postgresql.updates.json

@@ -1,4 +1,4 @@
 {
-  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000",
+  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=18;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Buffer Threshold Bytes=1000",  
   "Database": "postgresql"
 }

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-ado-my.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY PlatformBenchmarks .
 RUN dotnet publish -c Release -o out /p:DatabaseProvider=MySqlConnector
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY PlatformBenchmarks/appsettings.mysql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-ado-pg-up.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY PlatformBenchmarks .
 RUN dotnet publish -c Release -o out /p:DatabaseProvider=Npgsql
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY PlatformBenchmarks/appsettings.postgresql.updates.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-ado-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY PlatformBenchmarks .
 RUN dotnet publish -c Release -o out /p:DatabaseProvider=Npgsql
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY PlatformBenchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-ado-my.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.mysql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-ado-pg-up.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.updates.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-ado-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-dap-my.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.mysql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-dap-pg-up.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.updates.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-dap-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc-ef-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mvc.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-ado-my.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.mysql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-ado-pg-up.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.updates.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-ado-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-dap-my.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.mysql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-dap-pg-up.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.updates.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-dap-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-ef-pg.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.postgresql.json ./appsettings.json

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw-json.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore-mw.dockerfile

@@ -1,10 +1,16 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY Benchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 

+ 8 - 2
frameworks/CSharp/aspnetcore/aspcore.dockerfile

@@ -1,11 +1,17 @@
-FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:6.0.100-rc.1 AS build
 WORKDIR /app
 COPY PlatformBenchmarks .
 RUN dotnet publish -c Release -o out
 
-FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:6.0.0-rc.1 AS runtime
 ENV ASPNETCORE_URLS http://+:8080
 ENV DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS 1
+
+# Full PGO
+ENV DOTNET_TieredPGO 1 
+ENV DOTNET_TC_QuickJitForLoops 1 
+ENV DOTNET_ReadyToRun 0
+
 WORKDIR /app
 COPY --from=build /app/out ./
 COPY Benchmarks/appsettings.json ./appsettings.json

+ 203 - 0
frameworks/CSharp/aspnetcore/te.benchmarks.yml

@@ -0,0 +1,203 @@
+imports:
+  - https://raw.githubusercontent.com/dotnet/crank/main/src/Microsoft.Crank.Jobs.Wrk/wrk.yml
+  - https://github.com/aspnet/Benchmarks/blob/main/scenarios/aspnet.profiles.yml?raw=true
+
+# todo: change repository to TechEmpower
+# todo: change branch to master
+
+jobs:
+  aspnetcore:
+    source:
+      repository: https://github.com/sebastienros/FrameworkBenchmarks.git
+      branchOrCommit: sebros/net60
+      dockerContextDirectory: frameworks/CSharp/aspnetcore/
+    readyStateText: Application started.
+
+  postgresql:
+    source:
+      repository: https://github.com/TechEmpower/FrameworkBenchmarks.git
+      branchOrCommit: master
+      dockerFile: toolset/databases/postgres/postgres.dockerfile
+      dockerImageName: postgres_te
+      dockerContextDirectory: toolset/databases/postgres
+    readyStateText: ready to accept connections
+    noClean: true
+
+  mysql:
+    source:
+      repository: https://github.com/TechEmpower/FrameworkBenchmarks.git
+      branchOrCommit: master
+      dockerFile: toolset/databases/mysql/mysql.dockerfile
+      dockerImageName: mysql_te
+      dockerContextDirectory: toolset/databases/mysql
+    readyStateText: ready for connections
+    noClean: true
+
+scenarios:
+
+  plaintext:
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore.dockerfile
+          dockerImageName: aspcore
+    load:
+      job: wrk
+      variables:
+        presetHeaders: plaintext
+        path: /plaintext
+        pipeline: 16
+        serverPort: 8080
+        connections: 1024
+
+  plaintext_mw:
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-mw.dockerfile
+          dockerImageName: aspcore-mw
+    load:
+      job: wrk
+      variables:
+        presetHeaders: plaintext
+        path: /plaintext
+        pipeline: 16
+        serverPort: 8080
+        connections: 1024
+
+  json:
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore.dockerfile
+          dockerImageName: aspcore
+    load:
+      job: wrk
+      variables:
+        presetHeaders: json
+        path: /json
+        serverPort: 8080
+        connections: 512
+
+  fortunes:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-ado-pg.dockerfile
+          dockerImageName: aspcore-ado-pg
+    load:
+      job: wrk
+      variables:
+        presetHeaders: html
+        path: /fortunes
+        serverPort: 8080
+        connections: 512
+
+  single_query:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-ado-pg.dockerfile
+          dockerImageName: aspcore-ado-pg
+    load:
+      job: wrk
+      variables:
+        presetHeaders: json
+        path: /db
+        serverPort: 8080
+  
+  multiple_queries:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-ado-pg.dockerfile
+          dockerImageName: aspcore-ado-pg
+    load:
+      job: wrk
+      variables:
+        presetHeaders: json
+        path: /queries/20
+        serverPort: 8080
+
+  updates:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-ado-pg-up.dockerfile
+          dockerImageName: aspcore-ado-pg-up
+    load:
+      job: wrk
+      variables:
+        presetHeaders: json
+        path: /updates/20
+        serverPort: 8080
+
+  caching:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-ado-pg.dockerfile
+          dockerImageName: aspcore-ado-pg
+    load:
+      job: wrk
+      variables:
+        presetHeaders: json
+        path: /cached-worlds/100
+
+  fortunes_mysql:
+    db:
+      job: mysql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-ado-my.dockerfile
+          dockerImageName: aspcore-ado-my
+    load:
+      job: wrk
+      variables:
+        presetHeaders: html
+        path: /fortunes
+        serverPort: 8080
+        connections: 512
+
+  fortunes_mvc_ado_pg:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-mvc-ado-pg.dockerfile
+          dockerImageName: aspcore-mvc-ado-pg
+    load:
+      job: wrk
+      variables:
+        presetHeaders: html
+        path: /mvc/fortunes/raw
+        serverPort: 8080
+        connections: 512
+
+  fortunes_mvc_ef_pg:
+    db:
+      job: postgresql
+    application:
+      job: aspnetcore
+      source:
+          dockerFile: frameworks/CSharp/aspnetcore/aspcore-mvc-ef-pg.dockerfile
+          dockerImageName: aspcore-mvc-ef-pg
+    load:
+      job: wrk
+      variables:
+        presetHeaders: html
+        path: /mvc/fortunes/ef
+        serverPort: 8080
+        connections: 512

+ 2 - 0
frameworks/Elixir/phoenix/config/prod.exs

@@ -18,6 +18,8 @@ config :hello, Hello.Repo,
   queue_target: 5000,
   log: false
 
+config :phoenix, :logger, false
+
 config :logger,
   compile_time_purge_matching: [
     [level_lower_than: :error]

+ 1 - 8
frameworks/Elixir/phoenix/lib/hello_web.ex

@@ -37,14 +37,7 @@ defmodule HelloWeb do
         root: "lib/hello_web/templates",
         namespace: HelloWeb
 
-      # Import convenience functions from controllers
-      import Phoenix.Controller,
-        only: [get_csrf_token: 0, get_flash: 2, action_name: 1, controller_module: 1]
-
-      # Import all HTML functions (forms, tags, etc)
-      use Phoenix.HTML
-
-      import HelloWeb.Router.Helpers
+      alias HelloWeb.Router.Helpers, as: Routes
     end
   end
 

+ 33 - 30
frameworks/Elixir/phoenix/lib/hello_web/controllers/page_controller.ex

@@ -36,13 +36,13 @@ defmodule HelloWeb.PageController do
   end
 
   def queries(conn, params) do
+    :rand.seed(:exsp)
+
     resp =
-      params["queries"]
-      |> query_range()
-      |> parallel(fn _ ->
-        Repo.get(World, :rand.uniform(@random_max))
-      end)
-      |> Jason.encode!()
+      1..@random_max
+      |> Enum.take_random(size(params["queries"]))
+      |> parallel(fn idx -> Repo.get(World, idx) end)
+      |> Jason.encode_to_iodata!()
 
     conn
     |> put_resp_content_type(@json, nil)
@@ -63,25 +63,30 @@ defmodule HelloWeb.PageController do
   end
 
   def updates(conn, params) do
-    resp =
-      params["queries"]
-      |> query_range()
-      |> parallel(fn _ ->
-        Repo.checkout(fn ->
-          world =
-            World
-            |> Repo.get(:rand.uniform(@random_max))
-
-          world
-          |> Ecto.Changeset.change(randomnumber: random_but(world.randomnumber))
-          |> Repo.update!()
-        end)
+    :rand.seed(:exsp)
+
+    count = size(params["queries"])
+
+    worlds =
+      1..@random_max
+      |> Enum.take_random(count)
+      |> parallel(fn idx -> Repo.get(World, idx) end)
+      |> Enum.map(fn world ->
+        %{id: world.id, randomnumber: random_but(world.randomnumber)}
       end)
-      |> Jason.encode!()
+
+    {^count, result} =
+      Repo.insert_all(
+        World,
+        worlds,
+        on_conflict: :replace_all,
+        conflict_target: [:id],
+        returning: true
+      )
 
     conn
     |> put_resp_content_type(@json, nil)
-    |> send_resp(200, resp)
+    |> send_resp(200, Jason.encode_to_iodata!(result))
   end
 
   def plaintext(conn, _params) do
@@ -106,15 +111,13 @@ defmodule HelloWeb.PageController do
     |> Enum.map(&Task.await(&1))
   end
 
-  defp query_range(queries) do
-    try do
-      case String.to_integer(queries) do
-        x when x < 1 -> 1..1
-        x when x > 500 -> 1..500
-        x -> 1..x
-      end
-    rescue
-      ArgumentError -> 1..1
+  defp size(nil), do: 1
+
+  defp size(queries) do
+    case Integer.parse(queries) do
+      {x, ""} when x in 1..500 -> x
+      {x, ""} when x > 500 -> 500
+      _ -> 1
     end
   end
 end

+ 1 - 2
frameworks/Elixir/phoenix/mix.exs

@@ -36,8 +36,7 @@ defmodule Hello.Mixfile do
       {:postgrex, "~> 0.15"},
       {:plug_cowboy, "~> 2.0"},
       {:jason, "~> 1.2"},
-      {:phoenix_html, "~> 2.14"},
-      {:phoenix_live_reload, "~> 1.2", only: :dev}
+      {:phoenix_html, "~> 3.0"}
     ]
   end
 end

+ 6 - 10
frameworks/Elixir/phoenix/mix.lock

@@ -5,17 +5,13 @@
   "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
   "db_connection": {:hex, :db_connection, "2.4.0", "d04b1b73795dae60cead94189f1b8a51cc9e1f911c234cc23074017c43c031e5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad416c21ad9f61b3103d254a71b63696ecadb6a917b36f563921e0de00d7d7c8"},
   "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
-  "ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"},
-  "ecto_sql": {:hex, :ecto_sql, "3.6.2", "9526b5f691701a5181427634c30655ac33d11e17e4069eff3ae1176c764e0ba3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ec9d7e6f742ea39b63aceaea9ac1d1773d574ea40df5a53ef8afbd9242fdb6b"},
-  "eljiffy": {:hex, :eljiffy, "1.3.0", "7e584be454c5ec3fc3ae472eedb4cb2185e9ed6cd863df383ef601de3f3b27fd", [:mix], [{:jiffy, "~> 1.0", [hex: :jiffy, repo: "hexpm", optional: false]}], "hexpm", "90420512d60fb45bc9c09221b4d89cc539c9bfefc1c62f24cb3e2cb13acf2215"},
-  "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
+  "ecto": {:hex, :ecto, "3.7.0", "0b250b4aa5a9cdb80252802bd535c54c963e2d83f5bd179a57c093ed0779994b", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a212cecd544a6f3d00921bc3e7545070eb50b9a1454525323027bf07eba1165"},
+  "ecto_sql": {:hex, :ecto_sql, "3.7.0", "2fcaad4ab0c8d76a5afbef078162806adbe709c04160aca58400d5cbbe8eeac6", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a26135dfa1d99bf87a928c464cfa25bba6535a4fe761eefa56077a4febc60f70"},
   "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
-  "jiffy": {:hex, :jiffy, "1.0.8", "60e36f00be35e5ac6e6cf2d4caf3bdf3103d4460aff385f543a8d7df2d6d9613", [:rebar3], [], "hexpm", "f9ae986ba5a0854eb48cf6a76192d9367086da86c20197da430630be7c087a4e"},
-  "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
-  "phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"},
-  "phoenix_ecto": {:hex, :phoenix_ecto, "4.3.0", "2c69a452c2e0ee8c93345ae1cdc1696ef4877ff9cbb15c305def41960c3c4ebf", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0ac491924217550c8f42c81c1f390b5d81517d12ceaf9abf3e701156760a848e"},
-  "phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
-  "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
+  "mime": {:hex, :mime, "2.0.1", "0de4c81303fe07806ebc2494d5321ce8fb4df106e34dd5f9d787b637ebadc256", [:mix], [], "hexpm", "7a86b920d2aedce5fb6280ac8261ac1a739ae6c1a1ad38f5eadf910063008942"},
+  "phoenix": {:hex, :phoenix, "1.5.11", "1b60d59711d04a31afb0ea4f3a86c9b03646ce9a4760e5793ce48bc6f75a70e6", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3116c3aa2274ec0c3679995fe031af9bd68276a8e1b4997ab2d6ba15fe080724"},
+  "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
+  "phoenix_html": {:hex, :phoenix_html, "3.0.2", "0d71bd7dfa5fad2103142206e25e16accd64f41bcbd0002af3f0da17e530968d", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d6c6e85d9bef8d52a5a66fcccd15529651f379eaccbf10500343a17f6f814f82"},
   "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
   "plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
   "plug_cowboy": {:hex, :plug_cowboy, "2.5.1", "7cc96ff645158a94cf3ec9744464414f02287f832d6847079adfe0b58761cbd0", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "107d0a5865fa92bcb48e631cc0729ae9ccfa0a9f9a1bd8f01acb513abf1c2d64"},

+ 45 - 0
frameworks/Java/inverno/README.md

@@ -0,0 +1,45 @@
+# inverno Benchmarking Test
+
+### Test Type Implementation Source Code
+
+* [JSON](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+* [PLAINTEXT](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+* [DB](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+* [QUERY](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+* [CACHED QUERY](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+* [UPDATE](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+* [FORTUNES](src/main/java/com/techempower/inverno/benchmark/internal/Handler.java)
+
+## Important Libraries
+The tests were run with:
+* [Java OpenJDK 16](https://openjdk.java.net/)
+* [Inverno 1.2.1](https://inverno.io)
+
+## Test URLs
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext
+
+### DB
+
+http://localhost:8080/db
+
+### QUERY
+
+http://localhost:8080/query?queries=
+
+### CACHED QUERY
+
+http://localhost:8080/cached_query?queries=
+
+### UPDATE
+
+http://localhost:8080/update?queries=
+
+### FORTUNES
+
+http://localhost:8080/fortunes

+ 47 - 0
frameworks/Java/inverno/benchmark_config.json

@@ -0,0 +1,47 @@
+{
+  "framework": "inverno",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "None",
+        "framework": "inverno",
+        "language": "Java",
+        "flavor": "None",
+        "orm": "Micro",
+        "platform": "Inverno",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "inverno",
+        "notes": "",
+        "versus": "None"
+      },
+      "postgres": {
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "postgres",
+        "framework": "inverno",
+        "language": "Java",
+        "flavor": "None",
+        "orm": "Micro",
+        "platform": "Inverno",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "inverno",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 11 - 0
frameworks/Java/inverno/inverno-postgres.dockerfile

@@ -0,0 +1,11 @@
+FROM maven:3.8.2-openjdk-16 as maven
+WORKDIR /inverno
+COPY src src
+COPY pom.xml pom.xml
+RUN mvn package -q
+
+EXPOSE 8080
+
+# CMD [ "target/maven-inverno/application_linux_amd64/inverno-benchmark-1.0.0-SNAPSHOT/bin/inverno-benchmark" ]
+CMD export DBIP=`getent hosts tfb-database | awk '{ print $1 }'` && \
+    target/maven-inverno/application_linux_amd64/inverno-benchmark-1.0.0-SNAPSHOT/bin/inverno-benchmark --com.techempower.inverno.benchmark.appConfiguration.db_host=\"$DBIP\"

+ 9 - 0
frameworks/Java/inverno/inverno.dockerfile

@@ -0,0 +1,9 @@
+FROM maven:3.8.2-openjdk-16 as maven
+WORKDIR /inverno
+COPY src src
+COPY pom.xml pom.xml
+RUN mvn package -q
+
+EXPOSE 8080
+
+CMD [ "target/maven-inverno/application_linux_amd64/inverno-benchmark-1.0.0-SNAPSHOT/bin/inverno-benchmark", "--com.techempower.inverno.benchmark.appConfiguration.boot.reactor_prefer_vertx=false" ]

+ 125 - 0
frameworks/Java/inverno/pom.xml

@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>io.inverno.dist</groupId>
+		<artifactId>inverno-parent</artifactId>
+		<version>1.2.2</version>
+	</parent>
+	<groupId>com.techempower</groupId>
+	<artifactId>inverno-benchmark</artifactId>
+	<version>1.0.0-SNAPSHOT</version>
+	<packaging>jar</packaging>
+	
+	<name>inverno-benchmark</name>
+	<description>Inverno framework benchmark test</description>
+	
+	<properties>
+		<maven.compiler.source>16</maven.compiler.source>
+		<maven.compiler.target>16</maven.compiler.target>
+		<maven.compiler.release>16</maven.compiler.release>
+	</properties>
+	
+	<dependencies>
+		<dependency>
+			<groupId>io.inverno</groupId>
+			<artifactId>inverno-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.inverno.mod</groupId>
+			<artifactId>inverno-boot</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.inverno.mod</groupId>
+			<artifactId>inverno-configuration</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.inverno.mod</groupId>
+			<artifactId>inverno-http-server</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.inverno.mod</groupId>
+			<artifactId>inverno-irt</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>io.inverno.mod</groupId>
+			<artifactId>inverno-sql-vertx</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.unbescape</groupId>
+			<artifactId>unbescape</artifactId>
+			<version>1.1.6.RELEASE</version>
+		</dependency>
+		<dependency>
+			<groupId>io.vertx</groupId>
+			<artifactId>vertx-pg-client</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-codec-dns</artifactId>
+			<version>${version.netty}</version>
+		</dependency>
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-codec-socks</artifactId>
+			<version>${version.netty}</version>
+		</dependency>
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-handler-proxy</artifactId>
+			<version>${version.netty}</version>
+		</dependency>
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-resolver-dns</artifactId>
+			<version>${version.netty}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-transport-native-epoll</artifactId>
+			<classifier>linux-x86_64</classifier>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.apache.logging.log4j</groupId>
+			<artifactId>log4j-core</artifactId>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>io.inverno.tool</groupId>
+				<artifactId>inverno-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>inverno-package</id>
+						<phase>package</phase>
+						<goals>
+							<goal>build-app</goal>
+						</goals>
+						<configuration>
+							<vm>server</vm>
+							<launchers>
+								<launcher>
+									<name>inverno-benchmark</name>
+									<vmOptions>-Xms2g -Xmx2g -server -XX:+UseNUMA -XX:+UseParallelGC -Dio.netty.leakDetection.level=disabled -Dvertx.disableHttpHeadersValidation=true -Dvertx.disableMetrics=true -Dvertx.disableH2c=true -Dvertx.disableWebsockets=true -Dvertx.flashPolicyHandler=false -Dvertx.threadChecks=false -Dvertx.disableContextTimings=true -Dvertx.disableTCCL=true --add-modules io.netty.transport.unix.common,io.netty.transport.epoll</vmOptions>
+								</launcher>
+							</launchers>
+							<formats>
+								<format>zip</format>
+							</formats>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
+

+ 99 - 0
frameworks/Java/inverno/src/jmods/io.vertx.core/module-info.java

@@ -0,0 +1,99 @@
+module io.vertx.core {
+    requires io.netty.handler.proxy;
+    requires io.netty.resolver.dns;
+    requires io.netty.transport.epoll;
+    requires io.netty.transport.unix.common;
+    requires java.naming;
+    requires org.apache.logging.log4j;
+
+    requires transitive com.fasterxml.jackson.core;
+    requires transitive com.fasterxml.jackson.databind;
+    requires transitive io.netty.buffer;
+    requires transitive io.netty.codec;
+    requires transitive io.netty.codec.dns;
+    requires transitive io.netty.codec.http;
+    requires transitive io.netty.codec.http2;
+    requires transitive io.netty.common;
+    requires transitive io.netty.handler;
+    requires transitive io.netty.resolver;
+    requires transitive io.netty.transport;
+    requires transitive java.compiler;
+    requires transitive java.logging;
+
+    exports io.vertx.core;
+    exports io.vertx.core.buffer;
+    exports io.vertx.core.buffer.impl;
+    exports io.vertx.core.cli;
+    exports io.vertx.core.cli.annotations;
+    exports io.vertx.core.cli.converters;
+    exports io.vertx.core.cli.impl;
+    exports io.vertx.core.datagram;
+    exports io.vertx.core.datagram.impl;
+    exports io.vertx.core.dns;
+    exports io.vertx.core.dns.impl;
+    exports io.vertx.core.dns.impl.decoder;
+    exports io.vertx.core.eventbus;
+    exports io.vertx.core.eventbus.impl;
+    exports io.vertx.core.eventbus.impl.clustered;
+    exports io.vertx.core.eventbus.impl.codecs;
+    exports io.vertx.core.file;
+    exports io.vertx.core.file.impl;
+    exports io.vertx.core.http;
+    exports io.vertx.core.http.impl;
+    exports io.vertx.core.http.impl.cgbystrom;
+    exports io.vertx.core.http.impl.headers;
+    exports io.vertx.core.http.impl.ws;
+    exports io.vertx.core.impl;
+    exports io.vertx.core.impl.cpu;
+    exports io.vertx.core.impl.future;
+    exports io.vertx.core.impl.launcher;
+    exports io.vertx.core.impl.launcher.commands;
+    exports io.vertx.core.impl.logging;
+    exports io.vertx.core.impl.resolver;
+    exports io.vertx.core.impl.utils;
+    exports io.vertx.core.impl.verticle;
+    exports io.vertx.core.json;
+    exports io.vertx.core.json.impl;
+    exports io.vertx.core.json.jackson;
+    exports io.vertx.core.json.pointer;
+    exports io.vertx.core.json.pointer.impl;
+    exports io.vertx.core.logging;
+    exports io.vertx.core.metrics;
+    exports io.vertx.core.metrics.impl;
+    exports io.vertx.core.net;
+    exports io.vertx.core.net.impl;
+    exports io.vertx.core.net.impl.pkcs1;
+    exports io.vertx.core.net.impl.pool;
+    exports io.vertx.core.net.impl.transport;
+    exports io.vertx.core.parsetools;
+    exports io.vertx.core.parsetools.impl;
+    exports io.vertx.core.shareddata;
+    exports io.vertx.core.shareddata.impl;
+    exports io.vertx.core.spi;
+    exports io.vertx.core.spi.cluster;
+    exports io.vertx.core.spi.cluster.impl;
+    exports io.vertx.core.spi.cluster.impl.selector;
+    exports io.vertx.core.spi.json;
+    exports io.vertx.core.spi.launcher;
+    exports io.vertx.core.spi.logging;
+    exports io.vertx.core.spi.metrics;
+    exports io.vertx.core.spi.observability;
+    exports io.vertx.core.spi.resolver;
+    exports io.vertx.core.spi.tracing;
+    exports io.vertx.core.streams;
+    exports io.vertx.core.streams.impl;
+    exports io.vertx.core.tracing;
+
+    provides io.vertx.core.spi.launcher.CommandFactory with
+        io.vertx.core.impl.launcher.commands.RunCommandFactory,
+        io.vertx.core.impl.launcher.commands.VersionCommandFactory,
+        io.vertx.core.impl.launcher.commands.BareCommandFactory,
+        io.vertx.core.impl.launcher.commands.ListCommandFactory,
+        io.vertx.core.impl.launcher.commands.StartCommandFactory,
+        io.vertx.core.impl.launcher.commands.StopCommandFactory;
+    
+    uses io.vertx.core.spi.VertxServiceProvider;
+    uses io.vertx.core.spi.VerticleFactory;
+    uses io.vertx.core.spi.JsonFactory;
+
+}

+ 38 - 0
frameworks/Java/inverno/src/jmods/r2dbc.postgresql/module-info.java

@@ -0,0 +1,38 @@
+module r2dbc.postgresql {
+    requires com.ongres.scram.client;
+    requires com.ongres.scram.common;
+    requires io.netty.codec;
+    requires io.netty.resolver;
+    requires io.netty.transport;
+    requires io.netty.transport.epoll;
+    requires io.netty.transport.unix.common;
+    requires java.naming;
+
+    requires transitive io.netty.buffer;
+    requires transitive io.netty.common;
+    requires transitive io.netty.handler;
+    requires transitive org.reactivestreams;
+    requires transitive r2dbc.spi;
+    requires transitive reactor.core;
+    requires transitive reactor.netty.core;
+
+    exports io.r2dbc.postgresql;
+    exports io.r2dbc.postgresql.api;
+    exports io.r2dbc.postgresql.authentication;
+    exports io.r2dbc.postgresql.client;
+    exports io.r2dbc.postgresql.codec;
+    exports io.r2dbc.postgresql.extension;
+    exports io.r2dbc.postgresql.message;
+    exports io.r2dbc.postgresql.message.backend;
+    exports io.r2dbc.postgresql.message.frontend;
+    exports io.r2dbc.postgresql.replication;
+    exports io.r2dbc.postgresql.util;
+
+    provides io.r2dbc.postgresql.extension.Extension with
+        io.r2dbc.postgresql.codec.BuiltinDynamicCodecs;
+    provides io.r2dbc.spi.ConnectionFactoryProvider with
+        io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider;
+    
+    uses io.r2dbc.postgresql.extension.Extension;
+
+}

+ 36 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/AppConfiguration.java

@@ -0,0 +1,36 @@
+package com.techempower.inverno.benchmark;
+
+import io.inverno.core.annotation.NestedBean;
+import io.inverno.mod.boot.BootConfiguration;
+import io.inverno.mod.configuration.Configuration;
+import io.inverno.mod.http.server.HttpServerConfiguration;
+
+@Configuration
+public interface AppConfiguration {
+
+	@NestedBean
+	BootConfiguration boot();
+	
+	@NestedBean
+	HttpServerConfiguration http_server();
+	
+	default String db_database() {
+		return "postgres";
+	}
+	
+	default String db_host() {
+		return "localhost";
+	}
+	
+	default int db_port() {
+		return 5432;
+	}
+	
+	default String db_username() {
+		return "postgres";
+	}
+	
+	default String db_password() {
+		return "password";
+	}
+}

+ 21 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/Main.java

@@ -0,0 +1,21 @@
+package com.techempower.inverno.benchmark;
+
+import java.io.IOException;
+import java.util.function.Supplier;
+
+import io.inverno.core.annotation.Bean;
+import io.inverno.core.v1.Application;
+import io.inverno.mod.configuration.ConfigurationSource;
+import io.inverno.mod.configuration.source.BootstrapConfigurationSource;
+
+public class Main {
+
+	@Bean
+	public interface AppConfigurationSource extends Supplier<ConfigurationSource<?, ?, ?>> {}
+	
+	public static void main(String[] args) throws IllegalStateException, IOException {
+		Application.with(new Benchmark.Builder()
+			.setAppConfigurationSource(new BootstrapConfigurationSource(Main.class.getModule(), args))
+		).run();
+	}
+}

+ 306 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/Handler.java

@@ -0,0 +1,306 @@
+package com.techempower.inverno.benchmark.internal;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.techempower.inverno.benchmark.model.Fortune;
+import com.techempower.inverno.benchmark.model.Message;
+import com.techempower.inverno.benchmark.model.World;
+import com.techempower.inverno.benchmark.templates.FortunesTemplate;
+
+import io.inverno.core.annotation.Bean;
+import io.inverno.core.annotation.Bean.Visibility;
+import io.inverno.core.annotation.Destroy;
+import io.inverno.core.annotation.Init;
+import io.inverno.mod.base.Charsets;
+import io.inverno.mod.base.concurrent.Reactor;
+import io.inverno.mod.base.concurrent.ReactorScope;
+import io.inverno.mod.base.converter.ConverterException;
+import io.inverno.mod.http.base.HttpException;
+import io.inverno.mod.http.base.InternalServerErrorException;
+import io.inverno.mod.http.base.Parameter;
+import io.inverno.mod.http.base.Status;
+import io.inverno.mod.http.server.Exchange;
+import io.inverno.mod.http.server.ExchangeHandler;
+import io.inverno.mod.sql.SqlClient;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.EventLoopGroup;
+import io.netty.handler.codec.http.HttpHeaderNames;
+import io.netty.handler.codec.http.HttpHeaderValues;
+import io.netty.util.AsciiString;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Bean( visibility = Visibility.PRIVATE )
+public class Handler implements ExchangeHandler<Exchange> {
+
+	private static final String PATH_PLAINTEXT = "/plaintext";
+	private static final String PATH_JSON = "/json";
+	private static final String PATH_DB = "/db";
+	private static final String PATH_QUERIES = "/queries";
+	private static final String PATH_UPDATES = "/updates";
+	private static final String PATH_FORTUNES = "/fortunes";
+	
+	private static final CharSequence STATIC_SERVER = AsciiString.cached("inverno");
+
+	private final Reactor reactor;
+	private final ObjectMapper mapper;
+	private final ReactorScope<SqlClient> pooledClientSqlClient;
+	private final ReactorScope<SqlClient> poolSqlClient;
+	
+	private EventLoopGroup dateEventLoopGroup;
+	
+	private CharSequence date;
+	
+	public Handler(Reactor reactor, 
+			ObjectMapper mapper,
+			ReactorScope<SqlClient> pooledClientSqlClient,
+			ReactorScope<SqlClient> poolSqlClient
+		) {
+		this.reactor = reactor;
+		this.mapper = mapper;
+		this.pooledClientSqlClient = pooledClientSqlClient;
+		this.poolSqlClient = poolSqlClient;
+	}
+	
+	@Init
+	public void init() {
+		this.dateEventLoopGroup = this.reactor.createIoEventLoopGroup(1);
+		this.dateEventLoopGroup.scheduleAtFixedRate(() -> {
+			this.date = new AsciiString(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
+		}, 0, 1000, TimeUnit.MILLISECONDS);
+	}
+	
+	@Destroy
+	public void destroy() {
+		this.dateEventLoopGroup.shutdownGracefully();
+	}
+	
+	@Override
+	public void handle(Exchange exchange) throws HttpException {
+		switch(exchange.request().getPath()) {
+			case PATH_PLAINTEXT: {
+				this.handle_plaintext(exchange);
+				break;
+			}
+			case PATH_JSON: {
+				this.handle_json(exchange);
+				break;
+			}
+			case PATH_DB: {
+				this.handle_db(exchange);
+				break;
+			}
+			case PATH_FORTUNES: {
+				this.handle_fortunes(exchange);
+				break;
+			}
+			default: {
+				switch(exchange.request().getPathAbsolute()) {
+					case PATH_QUERIES: {
+						this.handle_queries(exchange);
+						break;
+					}
+					case PATH_UPDATES: {
+						this.handle_updates(exchange);
+						break;
+					}
+					default: {
+						exchange.response()
+							.headers(h -> h.status(Status.NOT_FOUND))
+							.body()
+								.empty();
+					}
+				}
+			}
+		}
+	}
+
+	private static final byte[] STATIC_PLAINTEXT = "Hello, World!".getBytes(Charsets.UTF_8);
+	private static final int STATIC_PLAINTEXT_LEN = STATIC_PLAINTEXT.length;
+
+	private static final ByteBuf STATIC_PLAINTEXT_BYTEBUF;
+	static {
+		ByteBuf tmpBuf = Unpooled.directBuffer(STATIC_PLAINTEXT_LEN);
+		tmpBuf.writeBytes(STATIC_PLAINTEXT);
+		STATIC_PLAINTEXT_BYTEBUF = Unpooled.unreleasableBuffer(tmpBuf);
+	}
+	
+	private static final CharSequence STATIC_PLAINTEXT_LEN_VALUE = AsciiString.cached(String.valueOf(STATIC_PLAINTEXT_LEN));
+	
+	private static class PlaintextSupplier implements Supplier<ByteBuf> {
+		@Override
+		public ByteBuf get() {
+			return STATIC_PLAINTEXT_BYTEBUF.duplicate();
+		}
+	}
+	
+	private static final Mono<ByteBuf> PLAIN_TEXT_MONO = Mono.fromSupplier(new PlaintextSupplier());
+	
+	public void handle_plaintext(Exchange exchange) throws HttpException {
+		exchange.response()
+			.headers(h -> h
+				.add(HttpHeaderNames.SERVER, STATIC_SERVER)
+				.add(HttpHeaderNames.DATE, date)
+				.add(HttpHeaderNames.CONTENT_LENGTH, STATIC_PLAINTEXT_LEN_VALUE)
+				.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
+			)
+			.body()
+				.raw()
+					.stream(PLAIN_TEXT_MONO);
+	}
+	
+	public void handle_json(Exchange exchange) throws HttpException {
+		try {
+			exchange.response()
+				.headers(h -> h
+					.add(HttpHeaderNames.SERVER, STATIC_SERVER)
+					.add(HttpHeaderNames.DATE, this.date)
+					.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON)
+				)
+				.body()
+					.raw()
+						.value(Unpooled.unreleasableBuffer(Unpooled.wrappedBuffer(this.mapper.writeValueAsBytes(new Message("Hello, World!")))));
+		} 
+		catch (JsonProcessingException | IllegalStateException e) {
+			throw new InternalServerErrorException("Error serializing message as JSON", e);
+		}
+	}
+
+	private static final String DB_SELECT_WORLD = "SELECT id, randomnumber from WORLD where id = $1";
+	
+	private static int randomWorldId() {
+		return 1 + ThreadLocalRandom.current().nextInt(10000);
+	}
+	
+	public void handle_db(Exchange exchange) throws HttpException {
+		exchange.response()
+			.headers(h -> h
+				.add(HttpHeaderNames.SERVER, STATIC_SERVER)
+				.add(HttpHeaderNames.DATE, this.date)
+				.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON)
+			)
+			.body()
+				.raw().stream(this.pooledClientSqlClient.get().queryForObject(
+						DB_SELECT_WORLD, 
+						row -> {
+							try {
+								return Unpooled.unreleasableBuffer(Unpooled.wrappedBuffer(this.mapper.writeValueAsBytes(new World(row.getInteger(0), row.getInteger(1)))));
+							} 
+							catch (JsonProcessingException e) {
+								throw new InternalServerErrorException(e);
+							}
+						}, 
+						randomWorldId()
+					)
+				);
+	}
+	
+	private static final String PARAMETER_QUERIES = "queries";
+
+	private int extractQueriesParameter(Exchange exchange) {
+		try {
+			return Math.min(500, Math.max(1, exchange.request().queryParameters().get(PARAMETER_QUERIES).map(Parameter::asInteger).orElse(1)));
+		}
+		catch (ConverterException e) { // TODO
+			return 1;
+		}
+	}
+	
+	public void handle_queries(Exchange exchange) throws HttpException {
+		int queries = this.extractQueriesParameter(exchange);
+		exchange.response()
+			.headers(h -> h
+				.add(HttpHeaderNames.SERVER, STATIC_SERVER)
+				.add(HttpHeaderNames.DATE, this.date)
+				.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON)
+			)
+			.body()
+				.raw().stream(Flux.range(0, queries)
+					.flatMap(ign -> this.pooledClientSqlClient.get().queryForObject(
+						DB_SELECT_WORLD, 
+						row -> new World(row.getInteger(0), row.getInteger(1)), 
+						randomWorldId()
+					))
+					.collectList()
+					.map(worlds -> {
+						try {
+							return Unpooled.unreleasableBuffer(Unpooled.wrappedBuffer(this.mapper.writeValueAsBytes(worlds)));
+						} 
+						catch (JsonProcessingException e) {
+							throw new InternalServerErrorException(e);
+						}
+					})
+				);
+	}
+	
+	private static final String DB_UPDATE_WORLD = "UPDATE world SET randomnumber=$1 WHERE id=$2";
+	
+	public void handle_updates(Exchange exchange) throws HttpException {
+		int queries = this.extractQueriesParameter(exchange);
+		
+		exchange.response()
+			.headers(h -> h
+				.add(HttpHeaderNames.SERVER, STATIC_SERVER)
+				.add(HttpHeaderNames.DATE, this.date)
+				.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON)
+			)
+			.body()
+				.raw().stream(this.poolSqlClient.get().connection(ops -> Flux.range(0, queries)
+					.flatMap(ign -> ops.queryForObject(
+							DB_SELECT_WORLD, 
+							row -> new World(row.getInteger(0), randomWorldId()), 
+							randomWorldId()
+						)
+					)
+					.collectSortedList()
+					.delayUntil(worlds -> ops.batchUpdate(
+							DB_UPDATE_WORLD, 
+							worlds.stream().map(world -> new Object[] { world.getRandomNumber(), world.getId() })
+						)
+					)
+					.map(worlds -> {
+						try {
+							return Unpooled.unreleasableBuffer(Unpooled.wrappedBuffer(this.mapper.writeValueAsBytes(worlds)));
+						} 
+						catch (JsonProcessingException e) {
+							throw new InternalServerErrorException(e);
+						}
+					}))
+				);
+	}
+	
+	private static final String DB_SELECT_FORTUNE = "SELECT id, message from FORTUNE";
+	private static final CharSequence MEDIA_TEXT_HTML_UTF8 = AsciiString.cached("text/html; charset=utf-8");
+	
+	private static final FortunesTemplate.Renderer<CompletableFuture<ByteBuf>> FORTUNES_RENDERER = FortunesTemplate.bytebuf(() -> Unpooled.unreleasableBuffer(Unpooled.buffer()));
+	
+	public void handle_fortunes(Exchange exchange) throws HttpException {
+		exchange.response()
+			.headers(h -> h
+				.add(HttpHeaderNames.SERVER, STATIC_SERVER)
+				.add(HttpHeaderNames.DATE, this.date)
+				.add(HttpHeaderNames.CONTENT_TYPE, MEDIA_TEXT_HTML_UTF8)
+			)
+			.body()
+				.raw().stream(Flux.from(this.pooledClientSqlClient.get().query(
+						DB_SELECT_FORTUNE, 
+						row -> new Fortune(row.getInteger(0), row.getString(1))
+					))
+					.collectList()
+					.flatMap(fortunes -> {
+						fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+						Collections.sort(fortunes);
+						return Mono.fromFuture(() -> FORTUNES_RENDERER.render(fortunes));
+					})
+				);
+	}
+}

+ 67 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/PoolSqlClientReactorScope.java

@@ -0,0 +1,67 @@
+package com.techempower.inverno.benchmark.internal;
+
+import com.techempower.inverno.benchmark.AppConfiguration;
+
+import io.inverno.core.annotation.Bean;
+import io.inverno.core.annotation.Destroy;
+import io.inverno.core.annotation.Init;
+import io.inverno.core.annotation.Bean.Visibility;
+import io.inverno.mod.base.concurrent.Reactor;
+import io.inverno.mod.base.concurrent.ReactorScope;
+import io.inverno.mod.base.concurrent.VertxReactor;
+import io.inverno.mod.sql.SqlClient;
+import io.inverno.mod.sql.vertx.PoolSqlClient;
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.pgclient.PgConnectOptions;
+import io.vertx.pgclient.PgPool;
+import io.vertx.sqlclient.PoolOptions;
+
+@Bean( name = "poolSqlClient", visibility = Visibility.PRIVATE )
+public class PoolSqlClientReactorScope extends ReactorScope<SqlClient> {
+
+	private final AppConfiguration configuration;
+	private final Reactor reactor;
+	
+	private Vertx vertx;
+	private PgConnectOptions connectOptions;
+	private PoolOptions poolOptions;
+	
+	public PoolSqlClientReactorScope(AppConfiguration configuration, Reactor reactor) {
+		this.configuration = configuration;
+		this.reactor = reactor;
+	}
+	
+	@Init
+	public void init() {
+		if(this.reactor instanceof VertxReactor) {
+			this.vertx = ((VertxReactor)this.reactor).getVertx();			
+		}
+		else {
+			this.vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(this.configuration.boot().prefer_native_transport()));
+		}
+		
+		this.connectOptions = new PgConnectOptions()
+				.setHost(this.configuration.db_host())
+				.setPort(this.configuration.db_port())
+				.setDatabase(this.configuration.db_database())
+				.setUser(this.configuration.db_username())
+				.setPassword(this.configuration.db_password())
+				.setCachePreparedStatements(true);
+		
+		this.poolOptions = new PoolOptions().setMaxSize(4);
+	}
+	
+	@Destroy
+	public void destroy() {
+		if(!(this.reactor instanceof VertxReactor)) {
+			this.vertx.close();			
+		}
+	}
+	
+	@Override
+	protected SqlClient create() {
+		return new PoolSqlClient(PgPool.pool(this.vertx, this.connectOptions, this.poolOptions));
+	}
+
+}

+ 67 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/internal/PooledClientSqlClientReactorScope.java

@@ -0,0 +1,67 @@
+package com.techempower.inverno.benchmark.internal;
+
+import com.techempower.inverno.benchmark.AppConfiguration;
+
+import io.inverno.core.annotation.Bean;
+import io.inverno.core.annotation.Bean.Visibility;
+import io.inverno.core.annotation.Destroy;
+import io.inverno.core.annotation.Init;
+import io.inverno.mod.base.concurrent.Reactor;
+import io.inverno.mod.base.concurrent.ReactorScope;
+import io.inverno.mod.base.concurrent.VertxReactor;
+import io.inverno.mod.sql.SqlClient;
+import io.inverno.mod.sql.vertx.PooledClientSqlClient;
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.pgclient.PgConnectOptions;
+import io.vertx.pgclient.PgPool;
+import io.vertx.sqlclient.PoolOptions;
+
+@Bean( name = "pooledClientSqlClient", visibility = Visibility.PRIVATE )
+public class PooledClientSqlClientReactorScope extends ReactorScope<SqlClient> {
+
+	private final AppConfiguration configuration;
+	private final Reactor reactor;
+	
+	private Vertx vertx;
+	private PgConnectOptions connectOptions;
+	private PoolOptions poolOptions;
+	
+	public PooledClientSqlClientReactorScope(AppConfiguration configuration, Reactor reactor) {
+		this.configuration = configuration;
+		this.reactor = reactor;
+	}
+	
+	@Init
+	public void init() {
+		if(this.reactor instanceof VertxReactor) {
+			this.vertx = ((VertxReactor)this.reactor).getVertx();			
+		}
+		else {
+			this.vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(this.configuration.boot().prefer_native_transport()));
+		}
+		
+		this.connectOptions = new PgConnectOptions()
+				.setHost(this.configuration.db_host())
+				.setPort(this.configuration.db_port())
+				.setDatabase(this.configuration.db_database())
+				.setUser(this.configuration.db_username())
+				.setPassword(this.configuration.db_password())
+				.setCachePreparedStatements(true);
+		
+		this.poolOptions = new PoolOptions().setMaxSize(1);
+	}
+	
+	@Destroy
+	public void destroy() {
+		if(!(this.reactor instanceof VertxReactor)) {
+			this.vertx.close();			
+		}
+	}
+	
+	@Override
+	protected SqlClient create() {
+		return new PooledClientSqlClient(PgPool.client(this.vertx, this.connectOptions, this.poolOptions));
+	}
+
+}

+ 25 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/model/Fortune.java

@@ -0,0 +1,25 @@
+package com.techempower.inverno.benchmark.model;
+
+public final class Fortune implements Comparable<Fortune> {
+
+	private final int id;
+	private final String message;
+
+	public Fortune(int id, String message) {
+		this.id = id;
+		this.message = message;
+	}
+
+	public int getId() {
+		return this.id;
+	}
+
+	public String getMessage() {
+		return this.message;
+	}
+
+	@Override
+	public int compareTo(Fortune other) {
+		return getMessage().compareTo(other.getMessage());
+	}
+}

+ 14 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/model/Message.java

@@ -0,0 +1,14 @@
+package com.techempower.inverno.benchmark.model;
+
+public final class Message {
+
+	private final String message;
+	
+	public Message(String message) {
+		this.message = message;
+	}
+
+	public String getMessage() {
+		return this.message;
+	}
+}

+ 33 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/model/World.java

@@ -0,0 +1,33 @@
+package com.techempower.inverno.benchmark.model;
+
+public final class World implements Comparable<World> {
+
+	private final int id;
+	private int randomNumber;
+
+	public World(int id) {
+		this.id = id;
+	}
+	
+	public World(int id, int randomNumber) {
+		this.id = id;
+		this.randomNumber = randomNumber;
+	}
+	
+	public int getId() {
+		return this.id;
+	}
+
+	public int getRandomNumber() {
+		return this.randomNumber;
+	}
+	
+	public void setRandomNumber(int randomNumber) {
+		this.randomNumber = randomNumber;
+	}
+
+	@Override
+	public int compareTo(World o) {
+		return Integer.compare(id, o.id);
+	}
+}

+ 30 - 0
frameworks/Java/inverno/src/main/java/com/techempower/inverno/benchmark/templates/FortunesTemplate.irt

@@ -0,0 +1,30 @@
+package com.techempower.inverno.benchmark.templates;
+
+import com.techempower.inverno.benchmark.model.Fortune;
+
+import java.util.List;
+import org.unbescape.html.HtmlEscape;
+
+option modes = {"STRING", "BYTEBUF", "STREAM", "PUBLISHER_STRING", "PUBLISHER_BYTEBUF"};
+option charset = "utf-8";
+
+(List<Fortune> fortunes) -> {
+<!DOCTYPE html>
+<html>
+<head><title>Fortunes</title></head>
+<body>
+<table>
+	<tr>
+		<th>id</th>
+		<th>message</th>
+	</tr>{fortunes}
+</table>
+</body>
+</html>
+}
+
+(Fortune fortune) -> {
+	<tr>
+		<td>{@fortune.id}</td>
+		<td>{@fortune.message|((String s) -> HtmlEscape.escapeHtml5Xml(s))}</td>
+	</tr>}

+ 28 - 0
frameworks/Java/inverno/src/main/java/module-info.java

@@ -0,0 +1,28 @@
[email protected]( excludes = { "io.inverno.mod.sql.vertx" } )
+
[email protected](beans="pooledClientSqlClient", into="handler:pooledClientSqlClient") 
[email protected](beans="poolSqlClient", into="handler:poolSqlClient") 
+module com.techempower.inverno.benchmark {
+	requires io.inverno.mod.boot;
+	requires io.inverno.mod.http.server;
+	requires io.inverno.mod.irt;
+	
+	requires io.inverno.mod.sql;
+	requires io.inverno.mod.sql.vertx;
+	
+	requires io.netty.common;
+	requires io.netty.codec.http;
+	requires unbescape;
+	
+	requires io.vertx.client.sql.pg;
+	requires io.vertx.client.sql;
+	requires io.vertx.core;
+	requires java.sql;
+	
+	requires transitive io.netty.transport;
+	requires static io.netty.transport.unix.common;
+	requires static io.netty.transport.epoll;
+	
+	exports com.techempower.inverno.benchmark;
+	exports com.techempower.inverno.benchmark.model;
+}

+ 16 - 0
frameworks/Java/inverno/src/main/resources/configuration.cprops

@@ -0,0 +1,16 @@
+com.techempower.inverno.benchmark.appConfiguration {
+	boot {
+		reactor_prefer_vertx = true
+		accept_backlog = null
+	}
+	http_server { 
+		tls_enabled = false
+		server_port = 8080
+		h2c_enabled = false
+	}
+	db_database = "hello_world"
+	db_host = "tfb-database"
+	db_port = 5432
+	db_username = "benchmarkdbuser"
+	db_password = "benchmarkdbpass"
+}

+ 4 - 4
frameworks/Java/officefloor/src/woof_benchmark_sqlclient/src/main/java/net/officefloor/benchmark/SqlClientOfficeFloorMain.java

@@ -130,7 +130,7 @@ public class SqlClientOfficeFloorMain implements DatabaseOperations {
 		// Nothing thread specific to set up
 	}
 
-	private static final int DB_COUNT = 2;
+	private static final int DB_COUNT = 1;
 
 	@Override
 	public void db(DbSendResponse sender) {
@@ -152,7 +152,7 @@ public class SqlClientOfficeFloorMain implements DatabaseOperations {
 				});
 	}
 
-	private static final int QUERIES_COUNT = 2;
+	private static final int QUERIES_COUNT = 1;
 
 	@Override
 	public void queries(int queryCount, QueriesSendResponse sender) {
@@ -182,7 +182,7 @@ public class SqlClientOfficeFloorMain implements DatabaseOperations {
 		}
 	}
 
-	private static final int FORTUNES_COUNT = 2;
+	private static final int FORTUNES_COUNT = 1;
 
 	@Override
 	public void fortunes(FortunesSendResponse sender) {
@@ -202,7 +202,7 @@ public class SqlClientOfficeFloorMain implements DatabaseOperations {
 				});
 	}
 
-	private static final int UPDATE_COUNT = 2;
+	private static final int UPDATE_COUNT = 1;
 
 	@Override
 	public void update(int queryCount, UpdateSendResponse sender) {

+ 25 - 3
frameworks/Java/redkale/benchmark_config.json

@@ -27,7 +27,7 @@
                 "db_url": "/db",
                 "query_url": "/queries?q=", 
                 "fortune_url": "/fortunes",
-                "update_url": "/updates?q=",
+                "update_url2": "/updates?q=",
                 "cached_query_url": "/cached-worlds?q=",
                 "port": 8080,
                 "approach": "Realistic",
@@ -50,7 +50,8 @@
                 "json_url": "/json",
                 "db_url": "/db",
                 "query_url": "/queries?q=", 
-                "update_url": "/updates?q=",
+                "fortune_url": "/fortunes",
+                "update_url2": "/updates?q=",
                 "cached_query_url": "/cached-worlds?q=",
                 "port": 8080,
                 "approach": "Realistic",
@@ -90,7 +91,7 @@
                 "db_url": "/db",
                 "query_url": "/queries?q=", 
                 "fortune_url": "/fortunes",
-                "update_url": "/updates?q=",
+                "update_url2": "/updates?q=",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
@@ -106,6 +107,27 @@
                 "display_name": "redkale-postgres",
                 "notes": "",
                 "versus": "Redkale"
+            },
+            "mongodb": {
+                "db_url": "/db",
+                "query_url": "/queries?q=", 
+                "fortune_url": "/fortunes",
+                "update_url": "/updates?q=",
+                "port": 8080,
+                "approach": "Realistic",
+                "classification": "Fullstack",
+                "database": "Mongodb",
+                "framework": "Redkale",
+                "language": "Java",
+                "flavor": "None",
+                "orm": "Raw",
+                "platform": "Redkale",
+                "webserver": "Redkale",
+                "os": "Linux",
+                "database_os": "Linux",
+                "display_name": "redkale-mongodb",
+                "notes": "",
+                "versus": "Redkale"
             }
         }
     ]

+ 3 - 8
frameworks/Java/redkale/conf/application.xml

@@ -5,13 +5,7 @@
     <resources>
         <executor threads="0"/>
         <properties>    
-            <property name="system.property.vertx.threadChecks" value="false"/> 
-            <property name="system.property.vertx.disableTCCL" value="true"/> 
-            <property name="system.property.vertx.disableMetrics" value="true"/> 
-            <property name="system.property.vertx.disableContextTimings" value="true"/> 
-            
-            <property name="system.property.redkale.convert.tiny" value="false"/>      
-            <property name="system.property.redkale.skip.counter" value="true"/>  
+            <property name="system.property.redkale.convert.tiny" value="false"/>    
             <property name="system.property.redkale.http.request.pipeline.sameheaders" value="true"/>  
             <property name="system.property.redkale.http.response.header.server" value="redkale"/>
             <property name="system.property.redkale.http.response.header.connection" value="none"/>
@@ -20,9 +14,10 @@
         
     <server protocol="HTTP" lazy="true" port="8080">      
         <response>
-            <contenttype plain="text/plain" json="application/json"/>  
+            <content-type plain="text/plain" json="application/json"/>  
             <date period="1000"/>
         </response>
+        <render value="org.redkalex.benchmark.FortuneRender"/>
         <services autoload="true"/>        
         <rest autoload="true"/>
         <servlets autoload="true"/>

+ 21 - 0
frameworks/Java/redkale/conf/persistence-mongodb.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="2.0">
+    
+    <persistence-unit name=".read" transaction-type="RESOURCE_LOCAL">
+        <properties>
+            <property name="javax.persistence.jdbc.url" value="mongodb://tfb-database/hello_world"/>
+            <property name="javax.persistence.connections.limit" value="512"/>
+            <property name="javax.persistence.jdbc.user" value="benchmarkdbuser"/>
+            <property name="javax.persistence.jdbc.password" value="benchmarkdbpass"/>
+        </properties>
+    </persistence-unit>
+    
+    <persistence-unit name=".write" transaction-type="RESOURCE_LOCAL">
+        <properties>
+            <property name="javax.persistence.jdbc.url" value="mongodb://tfb-database/hello_world"/>
+            <property name="javax.persistence.jdbc.user" value="benchmarkdbuser"/>
+            <property name="javax.persistence.jdbc.password" value="benchmarkdbpass"/>
+        </properties>
+    </persistence-unit>
+   
+</persistence>

+ 0 - 2
frameworks/Java/redkale/conf/persistence.xml

@@ -5,7 +5,6 @@
         <shared-cache-mode>ALL</shared-cache-mode>
         <properties>
             <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://tfb-database:5432/hello_world"/>
-            <property name="javax.persistence.jdbc.preparecache" value="true"/>
             <property name="javax.persistence.jdbc.user" value="benchmarkdbuser"/>
             <property name="javax.persistence.jdbc.password" value="benchmarkdbpass"/>
         </properties>
@@ -15,7 +14,6 @@
         <shared-cache-mode>ALL</shared-cache-mode>
         <properties>
             <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://tfb-database:5432/hello_world"/>
-            <property name="javax.persistence.jdbc.preparecache" value="true"/>
             <property name="javax.persistence.jdbc.user" value="benchmarkdbuser"/>
             <property name="javax.persistence.jdbc.password" value="benchmarkdbpass"/>
         </properties>

+ 19 - 3
frameworks/Java/redkale/config.toml

@@ -20,7 +20,7 @@ urls.json = "/json"
 urls.db = "/db"
 urls.fortune = "/fortunes"
 urls.query = "/queries?q="
-urls.update = "/updates?q="
+urls.update2 = "/updates?q="
 urls.cached_query = "/cached-worlds?q="
 approach = "Realistic"
 classification = "Fullstack"
@@ -36,8 +36,9 @@ versus = "Redkale"
 urls.plaintext = "/plaintext"
 urls.json = "/json"
 urls.db = "/db"
+urls.fortune = "/fortunes"
 urls.query = "/queries?q="
-urls.update = "/updates?q="
+urls.update2 = "/updates?q="
 urls.cached_query = "/cached-worlds?q="
 approach = "Realistic"
 classification = "Fullstack"
@@ -65,7 +66,7 @@ versus = "Redkale"
 urls.db = "/db"
 urls.fortune = "/fortunes"
 urls.query = "/queries?q="
-urls.update = "/updates?q="
+urls.update2 = "/updates?q="
 approach = "Realistic"
 classification = "Fullstack"
 database = "Postgres"
@@ -75,3 +76,18 @@ orm = "Raw"
 platform = "Redkale"
 webserver = "Redkale"
 versus = "Redkale"
+
+[mongodb]
+urls.db = "/db"
+urls.fortune = "/fortunes"
+urls.query = "/queries?q="
+urls.update = "/updates?q="
+approach = "Realistic"
+classification = "Fullstack"
+database = "Mongodb"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "Redkale"
+webserver = "Redkale"
+versus = "Redkale"

+ 5 - 35
frameworks/Java/redkale/pom-native.xml → frameworks/Java/redkale/pom-mongodb.xml

@@ -27,18 +27,11 @@
             <version>2.5.0-SNAPSHOT</version>
         </dependency>
         
-        <dependency> 
-            <groupId>com.fizzed</groupId>
-            <artifactId>rocker-compiler</artifactId>
-            <version>1.3.0</version>
-        </dependency> 
-        <!--
-        <dependency> 
-            <groupId>io.vertx</groupId>
-            <artifactId>vertx-pg-client</artifactId>
-            <version>4.1.2</version>
-        </dependency> 
-        -->
+        <dependency>
+            <groupId>org.mongodb</groupId>
+            <artifactId>mongodb-driver-reactivestreams</artifactId>
+            <version>4.3.1</version>
+        </dependency>
     </dependencies>
 
     <repositories>
@@ -102,29 +95,6 @@
                 </executions>    
             </plugin>
                  
-            <plugin>
-                <groupId>com.fizzed</groupId>
-                <artifactId>rocker-maven-plugin</artifactId>
-                <version>1.3.0</version>
-                <executions>
-                    <execution>
-                        <id>generate-rocker-templates</id>
-                        <phase>generate-sources</phase>
-                        <goals>
-                            <goal>generate</goal>
-                        </goals>
-                        <configuration>
-                            <javaVersion>1.8</javaVersion>
-                            <templateDirectory>${basedir}/src/main/templates</templateDirectory>
-                            <outputDirectory>${basedir}/target/generated-sources/rocker</outputDirectory>
-                            <discardLogicWhitespace>false</discardLogicWhitespace>
-                            <addAsSources>true</addAsSources>
-                            <optimize>true</optimize>
-                            <failOnError>true</failOnError>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>

+ 0 - 61
frameworks/Java/redkale/pom.xml

@@ -6,7 +6,6 @@
     <version>1.0.0</version>
 
     <properties>
-        <!-- the main class -->
         <main.class>org.redkale.boot.Application</main.class>
         <stack.version>1.0.0</stack.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -27,43 +26,6 @@
             <version>2.5.0-SNAPSHOT</version>
         </dependency>
         
-        <dependency> 
-            <groupId>com.fizzed</groupId>
-            <artifactId>rocker-compiler</artifactId>
-            <version>1.3.0</version>
-        </dependency> 
-        
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-all</artifactId>
-            <version>4.1.65.Final</version>
-        </dependency>
-        <!--
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-transport-native-epoll</artifactId>
-            <version>4.1.65.Final</version>
-            <classifier>linux-x86_64</classifier>
-        </dependency>
-        
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-transport-native-kqueue</artifactId>
-            <version>4.1.65.Final</version>
-            <classifier>osx-x86_64</classifier>
-        </dependency>
-        -->
-        <dependency> 
-            <groupId>io.vertx</groupId>
-            <artifactId>vertx-pg-client</artifactId>
-            <version>3.9.2</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>io.netty</groupId>
-                    <artifactId>*</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency> 
     </dependencies>
 
     <repositories>
@@ -127,29 +89,6 @@
                 </executions>    
             </plugin>
                  
-            <plugin>
-                <groupId>com.fizzed</groupId>
-                <artifactId>rocker-maven-plugin</artifactId>
-                <version>1.3.0</version>
-                <executions>
-                    <execution>
-                        <id>generate-rocker-templates</id>
-                        <phase>generate-sources</phase>
-                        <goals>
-                            <goal>generate</goal>
-                        </goals>
-                        <configuration>
-                            <javaVersion>1.8</javaVersion>
-                            <templateDirectory>${basedir}/src/main/templates</templateDirectory>
-                            <outputDirectory>${basedir}/target/generated-sources/rocker</outputDirectory>
-                            <discardLogicWhitespace>false</discardLogicWhitespace>
-                            <addAsSources>true</addAsSources>
-                            <optimize>true</optimize>
-                            <failOnError>true</failOnError>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>

+ 25 - 0
frameworks/Java/redkale/redkale-mongodb.dockerfile

@@ -0,0 +1,25 @@
+FROM openjdk:17-jdk-slim
+ARG DEBIAN_FRONTEND=noninteractive
+ARG MAVEN_VERSION=3.8.1
+
+WORKDIR /redkale
+RUN apt-get update -yqq
+RUN apt-get install -yqq wget
+
+RUN wget --no-verbose https://ftp.wayne.edu/apache/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz
+RUN tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz
+ENV MAVEN_HOME /redkale/apache-maven-${MAVEN_VERSION}
+ENV PATH $MAVEN_HOME/bin:$PATH
+
+COPY src src
+COPY conf conf
+COPY pom-mongodb.xml pom.xml
+RUN rm conf/persistence.xml
+RUN mv conf/persistence-mongodb.xml  conf/persistence.xml
+RUN mvn package -q
+
+RUN cp /redkale/target/redkale-benchmark-1.0.0.jar redkale-benchmark.jar
+
+EXPOSE 8080
+
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:AutoBoxCacheMax=80000", "-Dbenchmarks.db=true", "-DAPP_HOME=./", "-jar", "redkale-benchmark.jar"]

+ 1 - 1
frameworks/Java/redkale/redkale-native.dockerfile

@@ -2,7 +2,7 @@ FROM maven:3.6.3-openjdk-16-slim as maven
 WORKDIR /redkale
 COPY src src
 COPY conf conf
-COPY pom-native.xml pom.xml
+COPY pom.xml pom.xml
 RUN mvn package -q
 
 

+ 26 - 28
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/Service.java → frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/BenchmarkService.java

@@ -5,15 +5,13 @@
  */
 package org.redkalex.benchmark;
 
-import com.fizzed.rocker.RockerOutput;
-import com.fizzed.rocker.runtime.ArrayOfByteArraysOutput;
 import java.util.Random;
 import java.util.concurrent.*;
 import javax.annotation.Resource;
-import org.redkale.net.ChannelContext;
 import org.redkale.net.http.*;
 import org.redkale.service.AbstractService;
 import org.redkale.source.*;
+import org.redkale.util.Utility;
 import org.redkalex.benchmark.CachedWorld.WorldEntityCache;
 
 /**
@@ -21,17 +19,13 @@ import org.redkalex.benchmark.CachedWorld.WorldEntityCache;
  * @author zhangjx
  */
 @RestService(name = " ", repair = false)
-public class Service extends AbstractService {
+public class BenchmarkService extends AbstractService {
 
     private static final byte[] helloBytes = "Hello, world!".getBytes();
 
-    private final ThreadLocal<RedRandom> rands = ThreadLocal.withInitial(() -> new RedRandom());
-
     @Resource
     private DataSource source;
 
-    private WorldEntityCache cache;
-
     @RestMapping(name = "plaintext")
     public byte[] getHelloBytes() {
         return helloBytes;
@@ -43,45 +37,49 @@ public class Service extends AbstractService {
     }
 
     @RestMapping(name = "db")
-    public CompletableFuture<World> findWorldAsync(ChannelContext context) {
-        return source.findAsync(World.class, context, randomId(rands.get()));
+    public CompletableFuture<World> findWorldAsync() {
+        return source.findAsync(World.class, randomId(ThreadLocalRandom.current()));
     }
 
     @RestMapping(name = "queries")
-    public CompletableFuture<World[]> queryWorldAsync(ChannelContext context, int q) {
+    public CompletableFuture<World[]> queryWorldAsync(int q) {
         final int size = Math.min(500, Math.max(1, q));
-        final World[] worlds = new World[size];
-        final Random random = rands.get();
-        final CompletableFuture[] futures = new CompletableFuture[size];
+        final Random random = ThreadLocalRandom.current();
+        final CompletableFuture<World>[] futures = new CompletableFuture[size];
         for (int i = 0; i < size; i++) {
-            final int index = i;
-            futures[index] = source.findAsync(World.class, context, randomId(random)).thenAccept(v -> worlds[index] = v);
+            futures[i] = source.findAsync(World.class, randomId(random));
         }
-        return CompletableFuture.allOf(futures).thenApply(v -> worlds);
+        return Utility.allOfFutures(futures, c -> new World[c]);
     }
 
     @RestMapping(name = "updates")
-    public CompletableFuture<World[]> updateWorldAsync(ChannelContext context, int q) {
+    public CompletableFuture<World[]> updateWorldAsync(int q) {
         final int size = Math.min(500, Math.max(1, q));
-        final World[] worlds = new World[size];
         final Random random = ThreadLocalRandom.current();
-        final CompletableFuture[] futures = new CompletableFuture[size];
+        final CompletableFuture<World>[] futures = new CompletableFuture[size];
         for (int i = 0; i < size; i++) {
-            final int index = i;
-            futures[index] = source.findAsync(World.class, context, randomId(random)).thenAccept(v -> worlds[index] = v.randomNumber(randomId(random)));
+            futures[i] = source.findAsync(World.class, randomId(random));
         }
-        return CompletableFuture.allOf(futures).thenCompose(v -> source.updateAsync(context, World.sort(worlds))).thenApply(v -> worlds);
+        return CompletableFuture.allOf(futures).thenCompose(v -> {
+            final Random r = ThreadLocalRandom.current();
+            final World[] worlds = new World[size];
+            for (int i = 0; i < size; i++) {
+                worlds[i] = futures[i].join().randomNumber(randomId(r));
+            }
+            return source.updateAsync(World.sort(worlds)).thenApply(u -> worlds);
+        });
     }
 
     @RestMapping(name = "fortunes")
-    public CompletableFuture<HttpResult<byte[]>> queryFortunes() {
-        return source.queryListAsync(Fortune.class).thenApply((fortunes) -> {
+    public CompletableFuture<HttpScope> queryFortunes() {
+        return source.queryListAsync(Fortune.class).thenApply(fortunes -> {
             fortunes.add(new Fortune(0, "Additional fortune added at request time."));
-            RockerOutput out = FortunesTemplate.template(Fortune.sort(fortunes)).render();
-            return new HttpResult("text/html; charset=utf-8", ((ArrayOfByteArraysOutput) out).toByteArray());
+            return HttpScope.refer("").attr("fortunes", Fortune.sort(fortunes));
         });
     }
 
+    private WorldEntityCache cache;
+
     @RestMapping(name = "cached-worlds")
     public CachedWorld[] cachedWorlds(int q) {
         if (cache == null) {
@@ -90,7 +88,7 @@ public class Service extends AbstractService {
             }
         }
         final int size = Math.min(500, Math.max(1, q));
-        return cache.random(rands.get(), size);
+        return cache.random(ThreadLocalRandom.current(), size);
     }
 
     protected int randomId(Random rand) {

+ 7 - 7
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/CachedWorld.java

@@ -5,7 +5,7 @@
  */
 package org.redkalex.benchmark;
 
-import java.util.Random;
+import java.util.*;
 import javax.persistence.*;
 import org.redkale.convert.json.JsonConvert;
 import org.redkale.source.*;
@@ -57,10 +57,11 @@ public final class CachedWorld implements Comparable<CachedWorld> {
 
     public static class WorldEntityCache {
 
-        private Object[] array;
+        private CachedWorld[] array;
 
         public WorldEntityCache(DataSource source) {
-            this.array = source.queryList(CachedWorld.class).toArray();
+            List<CachedWorld> list = source.queryList(CachedWorld.class);
+            this.array = list.toArray(new CachedWorld[list.size()]);
         }
 
         public CachedWorld findAt(int index) {
@@ -68,12 +69,11 @@ public final class CachedWorld implements Comparable<CachedWorld> {
         }
 
         public CachedWorld[] random(Random random, int size) {
-            final CachedWorld[] worlds = new CachedWorld[size];
-            int count = size;
             Random rand = random;
-            for (int i = 0; i < count; i++) {
+            final CachedWorld[] worlds = new CachedWorld[size];
+            for (int i = 0; i < worlds.length; i++) {
                 long index = Math.abs(rand.nextLong()) % 10000;
-                worlds[i] = (CachedWorld) array[(int) index];
+                worlds[i] = array[(int) index];
             }
             return worlds;
         }

+ 63 - 0
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/FortuneRender.java

@@ -0,0 +1,63 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.redkalex.benchmark;
+
+import java.util.List;
+import org.redkale.convert.Convert;
+import org.redkale.net.http.*;
+import org.redkale.util.AnyValue;
+
+/**
+ *
+ * @author zhangjx
+ */
+public class FortuneRender implements org.redkale.net.http.HttpRender {
+
+    @Override
+    public void init(HttpContext context, AnyValue config) {
+    }
+
+    @Override
+    public void renderTo(HttpRequest request, HttpResponse response, Convert convert, HttpScope scope) {
+        StringBuilder sb = new StringBuilder(1200);
+        sb.append("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
+        for (Fortune item : (List<Fortune>) scope.find("fortunes")) {
+            sb.append("<tr><td>").append(item.getId()).append("</td><td>").append(escape(item.getMessage())).append("</td></tr>");
+        }
+        sb.append("</table></body></html>");
+        response.setContentType("text/html; charset=utf-8").finish(sb.toString());
+    }
+
+    private static CharSequence escape(CharSequence value) {
+        if (value == null || value.length() == 0) return "";
+        CharSequence cs = value;
+        StringBuilder sb = new StringBuilder(value.length() + 16);
+        for (int i = 0; i < cs.length(); i++) {
+            char ch = cs.charAt(i);
+            switch (ch) {
+                case '<':
+                    sb.append("&lt;");
+                    break;
+                case '>':
+                    sb.append("&gt;");
+                    break;
+                case '"':
+                    sb.append("&quot;");
+                    break;
+                case '\'':
+                    sb.append("&#39;");
+                    break;
+                case '&':
+                    sb.append("&amp;");
+                    break;
+                default:
+                    sb.append(ch);
+                    break;
+            }
+        }
+        return sb;
+    }
+}

+ 0 - 45
frameworks/Java/redkale/src/main/java/org/redkalex/benchmark/RedRandom.java

@@ -1,45 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.redkalex.benchmark;
-
-import java.util.Random;
-
-/**
- *
- * @author zhangjx
- */
-public class RedRandom extends Random {
-
-    private long s0, s1;
-
-    public RedRandom() {
-        this.s0 = super.nextLong();
-        this.s1 = super.nextLong();
-    }
-
-    @Override
-    public long nextLong() {
-        final long s0 = this.s0;
-        long s1 = this.s1;
-        final long result = s0 + s1;
-        s1 ^= s0;
-        this.s0 = Long.rotateLeft(s0, 24) ^ s1 ^ s1 << 16;
-        this.s1 = Long.rotateLeft(s1, 37);
-        return result;
-    }
-
-    @Override
-    public int nextInt() {
-        return (int) nextLong();
-    }
-
-    @Override
-    public int nextInt(int bound) {
-        long s = nextLong();
-        return (int) (s < 0 ? -s : s) % bound;
-    }
-
-}

+ 0 - 9
frameworks/Java/redkale/src/main/templates/org/redkalex/benchmark/FortunesTemplate.rocker.html

@@ -1,9 +0,0 @@
-@import org.redkalex.benchmark.Fortune
-@import java.util.List
-@args(List<Fortune> fortunes)
-<!DOCTYPE html><html>
-<head><title>Fortunes</title></head>
-<body><table>
-<tr><th>id</th><th>message</th></tr>@for (fortune : fortunes) {
-<tr><td>@fortune.getId()</td><td>@fortune.getMessage()</td></tr>} 
-</table></body></html>

+ 2 - 2
frameworks/Java/vertx/README.md

@@ -28,8 +28,8 @@ This is the Vert.x portion of a [benchmarking test suite](../) comparing a varie
 
 ## Versions
 
-* [Java OpenJDK 1.8](http://openjdk.java.net/)
-* [vertx 3.6.0.CR1](http://vertx.io/)
+* [Java 11](https://jdk.java.net)
+* [vertx 4.1.3](http://vertx.io/)
 
 ## Test URLs
 

+ 13 - 7
frameworks/Java/vertx/pom.xml

@@ -10,8 +10,9 @@
 		<maven.compiler.target>11</maven.compiler.target>
 		<!-- the main class -->
 		<main.class>vertx.App</main.class>
-		<stack.version>3.7.0</stack.version>
-		<netty.version>4.1.36.Final</netty.version>
+		<stack.version>4.1.4</stack.version>
+		<jackson.version>2.11.4</jackson.version>
+		<netty.version>4.1.67.Final</netty.version>
 	</properties>
 
 	<dependencies>
@@ -20,6 +21,16 @@
 			<artifactId>vertx-core</artifactId>
 			<version>${stack.version}</version>
 		</dependency>
+		<dependency>
+			<groupId>io.vertx</groupId>
+			<artifactId>vertx-pg-client</artifactId>
+			<version>${stack.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>${jackson.version}</version>
+		</dependency>
 		<dependency>
 			<groupId>io.netty</groupId>
 			<artifactId>netty-transport-native-kqueue</artifactId>
@@ -32,11 +43,6 @@
 			<version>${netty.version}</version>
 			<classifier>linux-x86_64</classifier>
 		</dependency>
-		<dependency>
-			<groupId>io.reactiverse</groupId>
-			<artifactId>reactive-pg-client</artifactId>
-			<version>0.11.3</version>
-		</dependency>
 		<dependency>
 			<groupId>com.fizzed</groupId>
 			<artifactId>rocker-compiler</artifactId>

+ 1 - 2
frameworks/Java/vertx/src/main/conf/config.json

@@ -2,6 +2,5 @@
   "host": "tfb-database",
   "username": "benchmarkdbuser",
   "password": "benchmarkdbpass",
-  "database": "hello_world",
-  "maxPoolSize": 64
+  "database": "hello_world"
 }

+ 108 - 68
frameworks/Java/vertx/src/main/java/vertx/App.java

@@ -2,7 +2,8 @@ package vertx;
 
 import com.fizzed.rocker.ContentType;
 import com.fizzed.rocker.RockerOutputFactory;
-import io.reactiverse.pgclient.*;
+import io.netty.util.concurrent.MultithreadEventExecutorGroup;
+import io.vertx.pgclient.*;
 import io.vertx.core.*;
 import io.vertx.core.buffer.Buffer;
 import io.vertx.core.http.HttpHeaders;
@@ -15,6 +16,15 @@ import io.vertx.core.json.JsonArray;
 import io.vertx.core.json.JsonObject;
 import io.vertx.core.logging.Logger;
 import io.vertx.core.logging.LoggerFactory;
+import io.vertx.sqlclient.PoolOptions;
+import io.vertx.sqlclient.PreparedQuery;
+import io.vertx.sqlclient.PreparedStatement;
+import io.vertx.sqlclient.Row;
+import io.vertx.sqlclient.RowIterator;
+import io.vertx.sqlclient.RowSet;
+import io.vertx.sqlclient.Tuple;
+import io.vertx.sqlclient.impl.SqlClientInternal;
+import io.vertx.sqlclient.impl.command.CompositeCommand;
 import vertx.model.Fortune;
 import vertx.model.Message;
 import vertx.model.World;
@@ -65,12 +75,14 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
   private static final String PATH_UPDATES = "/updates";
   private static final String PATH_FORTUNES = "/fortunes";
 
+  private static final Handler<AsyncResult<Void>> NULL_HANDLER = null;
+
   private static final CharSequence RESPONSE_TYPE_PLAIN = HttpHeaders.createOptimized("text/plain");
   private static final CharSequence RESPONSE_TYPE_HTML = HttpHeaders.createOptimized("text/html; charset=UTF-8");
   private static final CharSequence RESPONSE_TYPE_JSON = HttpHeaders.createOptimized("application/json");
 
   private static final String HELLO_WORLD = "Hello, world!";
-  private static final Buffer HELLO_WORLD_BUFFER = Buffer.factory.directBuffer(HELLO_WORLD, "UTF-8");
+  private static final Buffer HELLO_WORLD_BUFFER = Buffer.buffer(HELLO_WORLD, "UTF-8");
 
   private static final CharSequence HEADER_SERVER = HttpHeaders.createOptimized("server");
   private static final CharSequence HEADER_DATE = HttpHeaders.createOptimized("date");
@@ -86,8 +98,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
 
   private HttpServer server;
 
-  private PgClient client;
-  private PgPool pool;
+  private SqlClientInternal client;
 
   private CharSequence dateString;
 
@@ -95,12 +106,16 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
 
   private final RockerOutputFactory<BufferRockerOutput> factory = BufferRockerOutput.factory(ContentType.RAW);
 
+  private PreparedQuery<RowSet<Row>> SELECT_WORLD_QUERY;
+  private PreparedQuery<RowSet<Row>> SELECT_FORTUNE_QUERY;
+  private PreparedQuery<RowSet<Row>> UPDATE_WORLD_QUERY;
+
   public static CharSequence createDateHeader() {
     return HttpHeaders.createOptimized(DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
   }
 
   @Override
-  public void start() throws Exception {
+  public void start(Promise<Void> startPromise) throws Exception {
     int port = 8080;
     server = vertx.createHttpServer(new HttpServerOptions());
     server.requestHandler(App.this).listen(port);
@@ -112,15 +127,24 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
         HEADER_CONTENT_LENGTH, HELLO_WORLD_LENGTH };
     JsonObject config = config();
     vertx.setPeriodic(1000, id -> plaintextHeaders[5] = dateString = createDateHeader());
-    PgPoolOptions options = new PgPoolOptions();
-    options.setDatabase(config.getString("database"));
-    options.setHost(config.getString("host"));
+    PgConnectOptions options = new PgConnectOptions();
+    options.setDatabase(config.getString("database", "hello_world"));
+    options.setHost(config.getString("host", "tfb-database"));
     options.setPort(config.getInteger("port", 5432));
-    options.setUser(config.getString("username"));
-    options.setPassword(config.getString("password"));
+    options.setUser(config.getString("username", "benchmarkdbuser"));
+    options.setPassword(config.getString("password", "benchmarkdbpass"));
     options.setCachePreparedStatements(true);
-    client = PgClient.pool(vertx, new PgPoolOptions(options).setMaxSize(1));
-    pool = PgClient.pool(vertx, new PgPoolOptions(options).setMaxSize(4));
+    options.setPipeliningLimit(100_000); // Large pipelining means less flushing and we use a single connection anyway
+    PgConnection.connect(vertx, options).flatMap(conn -> {
+      client = (SqlClientInternal)conn;
+      Future<PreparedStatement> f1 = conn.prepare(SELECT_WORLD);
+      Future<PreparedStatement> f2 = conn.prepare(SELECT_FORTUNE);
+      Future<PreparedStatement> f3 = conn.prepare(UPDATE_WORLD);
+      f1.onSuccess(ps -> SELECT_WORLD_QUERY = ps.query());
+      f2.onSuccess(ps -> SELECT_FORTUNE_QUERY = ps.query());
+      f3.onSuccess(ps -> UPDATE_WORLD_QUERY = ps.query());
+      return CompositeFuture.all(f1, f2, f3);
+    }).onComplete(ar -> startPromise.complete());
   }
 
   @Override
@@ -136,7 +160,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
         handleDb(request);
         break;
       case PATH_QUERIES:
-        new Queries().handle(request);
+        new Queries(request).handle();
         break;
       case PATH_UPDATES:
         new Update(request).handle();
@@ -162,7 +186,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
     for (int i = 0;i < plaintextHeaders.length; i+= 2) {
       headers.add(plaintextHeaders[i], plaintextHeaders[i + 1]);
     }
-    response.end(HELLO_WORLD_BUFFER);
+    response.end(HELLO_WORLD_BUFFER, NULL_HANDLER);
   }
 
   private void handleJson(HttpServerRequest request) {
@@ -172,7 +196,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
         .add(HEADER_CONTENT_TYPE, RESPONSE_TYPE_JSON)
         .add(HEADER_SERVER, SERVER)
         .add(HEADER_DATE, dateString);
-    response.end(new Message("Hello, World!").toBuffer());
+    response.end(new Message("Hello, World!").toBuffer(), NULL_HANDLER);
   }
 
   /**
@@ -187,19 +211,19 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
 
   private void handleDb(HttpServerRequest req) {
     HttpServerResponse resp = req.response();
-    client.preparedQuery(SELECT_WORLD, Tuple.of(randomWorld()), res -> {
+    SELECT_WORLD_QUERY.execute(Tuple.of(randomWorld()), res -> {
       if (res.succeeded()) {
-        PgIterator resultSet = res.result().iterator();
+        RowIterator<Row> resultSet = res.result().iterator();
         if (!resultSet.hasNext()) {
           resp.setStatusCode(404).end();
           return;
         }
-        Tuple row = resultSet.next();
+        Row row = resultSet.next();
         resp
             .putHeader(HttpHeaders.SERVER, SERVER)
             .putHeader(HttpHeaders.DATE, dateString)
             .putHeader(HttpHeaders.CONTENT_TYPE, RESPONSE_TYPE_JSON)
-            .end(Json.encode(new World(row.getInteger(0), row.getInteger(1))));
+            .end(Json.encode(new World(row.getInteger(0), row.getInteger(1))), NULL_HANDLER);
       } else {
         logger.error(res.cause());
         resp.setStatusCode(500).end(res.cause().getMessage());
@@ -207,37 +231,50 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
     });
   }
 
-  class Queries {
+
+  class Queries implements Handler<AsyncResult<RowSet<Row>>> {
 
     boolean failed;
     JsonArray worlds = new JsonArray();
+    final HttpServerRequest req;
+    final HttpServerResponse resp;
+    final int queries;
 
-    private void handle(HttpServerRequest req) {
-      HttpServerResponse resp = req.response();
-      final int queries = getQueries(req);
-      for (int i = 0; i < queries; i++) {
-        client.preparedQuery(SELECT_WORLD, Tuple.of(randomWorld()), ar -> {
-          if (!failed) {
-            if (ar.failed()) {
-              failed = true;
-              resp.setStatusCode(500).end(ar.cause().getMessage());
-              return;
-            }
+    public Queries(HttpServerRequest req) {
+      this.req = req;
+      this.resp = req.response();
+      this.queries = getQueries(req);
+    }
 
-            // we need a final reference
-            final Tuple row = ar.result().iterator().next();
-            worlds.add(new JsonObject().put("id", "" + row.getInteger(0)).put("randomNumber", "" + row.getInteger(1)));
-
-            // stop condition
-            if (worlds.size() == queries) {
-              resp
-                  .putHeader(HttpHeaders.SERVER, SERVER)
-                  .putHeader(HttpHeaders.DATE, dateString)
-                  .putHeader(HttpHeaders.CONTENT_TYPE, RESPONSE_TYPE_JSON)
-                  .end(worlds.encode());
-            }
-          }
-        });
+    private void handle() {
+      client.group(c -> {
+        for (int i = 0; i < queries; i++) {
+          c.preparedQuery(SELECT_WORLD).execute(Tuple.of(randomWorld()), this);
+        }
+      });
+    }
+
+    @Override
+    public void handle(AsyncResult<RowSet<Row>> ar) {
+      if (!failed) {
+        if (ar.failed()) {
+          failed = true;
+          resp.setStatusCode(500).end(ar.cause().getMessage());
+          return;
+        }
+
+        // we need a final reference
+        final Tuple row = ar.result().iterator().next();
+        worlds.add(new JsonObject().put("id", "" + row.getInteger(0)).put("randomNumber", "" + row.getInteger(1)));
+
+        // stop condition
+        if (worlds.size() == queries) {
+          resp
+              .putHeader(HttpHeaders.SERVER, SERVER)
+              .putHeader(HttpHeaders.DATE, dateString)
+              .putHeader(HttpHeaders.CONTENT_TYPE, RESPONSE_TYPE_JSON)
+              .end(worlds.encode(), NULL_HANDLER);
+        }
       }
     }
   }
@@ -257,27 +294,21 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
 
     private void handle() {
 
-      pool.getConnection(ar1 -> {
-        if (ar1.failed()) {
-          failed = true;
-          sendError(ar1.cause());
-          return;
-        }
-        PgConnection conn = ar1.result();
+      client.group(c -> {
+        PreparedQuery<RowSet<Row>> preparedQuery = c.preparedQuery(SELECT_WORLD);
         for (int i = 0; i < worlds.length; i++) {
           int id = randomWorld();
           int index = i;
-          conn.preparedQuery(SELECT_WORLD, Tuple.of(id), ar2 -> {
+          preparedQuery.execute(Tuple.of(id), ar2 -> {
             if (!failed) {
               if (ar2.failed()) {
-                conn.close();
                 failed = true;
                 sendError(ar2.cause());
                 return;
               }
               worlds[index] = new World(ar2.result().iterator().next().getInteger(0), randomWorld());
               if (++queryCount == worlds.length) {
-                handleUpdates(conn);
+                handleUpdates();
               }
             }
           });
@@ -285,16 +316,15 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
       });
     }
 
-    void handleUpdates(PgConnection conn) {
+    void handleUpdates() {
       Arrays.sort(worlds);
       List<Tuple> batch = new ArrayList<>();
       for (World world : worlds) {
         batch.add(Tuple.of(world.getRandomNumber(), world.getId()));
       }
-      conn.preparedBatch(UPDATE_WORLD, batch, ar -> {
-        conn.close();
-        if (ar.failed()) {
-          sendError(ar.cause());
+      UPDATE_WORLD_QUERY.executeBatch(batch, ar2 -> {
+        if (ar2.failed()) {
+          sendError(ar2.cause());
           return;
         }
         JsonArray json = new JsonArray();
@@ -305,7 +335,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
             .putHeader(HttpHeaders.SERVER, SERVER)
             .putHeader(HttpHeaders.DATE, dateString)
             .putHeader(HttpHeaders.CONTENT_TYPE, RESPONSE_TYPE_JSON)
-            .end(json.toBuffer());
+            .end(json.toBuffer(), NULL_HANDLER);
       });
     }
 
@@ -316,17 +346,17 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
   }
 
   private void handleFortunes(HttpServerRequest req) {
-    client.preparedQuery(SELECT_FORTUNE, ar -> {
+    SELECT_FORTUNE_QUERY.execute(ar -> {
       HttpServerResponse response = req.response();
       if (ar.succeeded()) {
         List<Fortune> fortunes = new ArrayList<>();
-        PgIterator resultSet = ar.result().iterator();
+        RowIterator<Row> resultSet = ar.result().iterator();
         if (!resultSet.hasNext()) {
           response.setStatusCode(404).end("No results");
           return;
         }
         while (resultSet.hasNext()) {
-          Tuple row = resultSet.next();
+          Row row = resultSet.next();
           fortunes.add(new Fortune(row.getInteger(0), row.getString(1)));
         }
         fortunes.add(new Fortune(0, "Additional fortune added at request time."));
@@ -335,7 +365,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
             .putHeader(HttpHeaders.SERVER, SERVER)
             .putHeader(HttpHeaders.DATE, dateString)
             .putHeader(HttpHeaders.CONTENT_TYPE, RESPONSE_TYPE_HTML)
-            .end(FortunesTemplate.template(fortunes).render(factory).buffer());
+            .end(FortunesTemplate.template(fortunes).render(factory).buffer(), NULL_HANDLER);
       } else {
         Throwable err = ar.cause();
         logger.error("", err);
@@ -345,14 +375,24 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
   }
 
   public static void main(String[] args) throws Exception {
+
+    int eventLoopPoolSize = VertxOptions.DEFAULT_EVENT_LOOP_POOL_SIZE;
+    String sizeProp = System.getProperty("vertx.eventLoopPoolSize");
+    if (sizeProp != null) {
+      try {
+        eventLoopPoolSize = Integer.parseInt(sizeProp);
+      } catch (NumberFormatException e) {
+        e.printStackTrace();
+      }
+    }
     JsonObject config = new JsonObject(new String(Files.readAllBytes(new File(args[0]).toPath())));
-    Vertx vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true));
+    Vertx vertx = Vertx.vertx(new VertxOptions().setEventLoopPoolSize(eventLoopPoolSize).setPreferNativeTransport(true));
     vertx.exceptionHandler(err -> {
       err.printStackTrace();
     });
     printConfig(vertx);
     vertx.deployVerticle(App.class.getName(),
-        new DeploymentOptions().setInstances(VertxOptions.DEFAULT_EVENT_LOOP_POOL_SIZE).setConfig(config), event -> {
+        new DeploymentOptions().setInstances(eventLoopPoolSize).setConfig(config), event -> {
           if (event.succeeded()) {
             logger.info("Server listening on port " + 8080);
           } else {
@@ -383,7 +423,7 @@ public class App extends AbstractVerticle implements Handler<HttpServerRequest>
       logger.error("Could not read Vertx version", e);;
     }
     logger.info("Vertx: " + version);
-    logger.info("Event Loop Size: " + VertxOptions.DEFAULT_EVENT_LOOP_POOL_SIZE);
+    logger.info("Event Loop Size: " + ((MultithreadEventExecutorGroup)vertx.nettyEventLoopGroup()).executorCount());
     logger.info("Native transport : " + nativeTransport);
   }
 }

+ 3 - 0
frameworks/Java/vertx/vertx-postgres.dockerfile

@@ -23,6 +23,9 @@ CMD export DBIP=`getent hosts tfb-database | awk '{ print $1 }'` && \
       -Dvertx.disableContextTimings=true \
       -Dvertx.disableTCCL=true \
       -Dvertx.disableHttpHeadersValidation=true \
+      -Dvertx.eventLoopPoolSize=$((`grep --count ^processor /proc/cpuinfo`)) \
+      -Dio.netty.buffer.checkBounds=false  \
+      -Dio.netty.buffer.checkAccessible=false \
       -jar \
       target/vertx.benchmark-0.0.1-SNAPSHOT-fat.jar \
       src/main/conf/config.json

+ 1 - 1
frameworks/Java/vertx/vertx.dockerfile

@@ -6,4 +6,4 @@ RUN mvn package -q
 
 EXPOSE 8080
 
-CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dvertx.disableHttpHeadersValidation=true", "-jar", "target/vertx.benchmark-0.0.1-SNAPSHOT-fat.jar", "src/main/conf/config.json"]
+CMD ["java", "-Xms2G", "-Xmx2G", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-Dvertx.disableMetrics=true", "-Dvertx.disableH2c=true", "-Dvertx.disableWebsockets=true", "-Dvertx.flashPolicyHandler=false", "-Dvertx.threadChecks=false", "-Dvertx.disableContextTimings=true", "-Dvertx.disableTCCL=true", "-Dvertx.disableHttpHeadersValidation=true", "-Dio.netty.buffer.checkBounds=false", "-Dio.netty.buffer.checkAccessible=false", "-jar", "target/vertx.benchmark-0.0.1-SNAPSHOT-fat.jar", "src/main/conf/config.json"]

+ 1 - 1
frameworks/Java/wildfly-ee/wildfly-ee.dockerfile

@@ -1,4 +1,4 @@
-FROM maven:3.6.3-openjdk-16
+FROM maven:3-openjdk-17
 WORKDIR /wildfly
 EXPOSE 8080
 ENV MAVEN_OPTS="--add-exports=java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED --add-exports=java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED"

+ 1 - 1
frameworks/JavaScript/express/README.md

@@ -12,7 +12,7 @@ This is the Express portion of a [benchmarking test suite](../) comparing a vari
 
 ## Infrastructure Software Versions
 The tests were run with:
-* [Node.js v14.17.5](http://nodejs.org/)
+* [Node.js v16.9.1](http://nodejs.org/)
 * [Express 4.17.1](http://expressjs.com/)
 
 ## Resources

+ 1 - 1
frameworks/JavaScript/express/express-mongodb.dockerfile

@@ -1,4 +1,4 @@
-FROM node:14.17.5-slim
+FROM node:16.9.1-slim
 
 COPY ./ ./
 

+ 1 - 1
frameworks/JavaScript/express/express-mysql.dockerfile

@@ -1,4 +1,4 @@
-FROM node:14.17.5-slim
+FROM node:16.9.1-slim
 
 COPY ./ ./
 

+ 1 - 1
frameworks/JavaScript/express/express-postgres.dockerfile

@@ -1,4 +1,4 @@
-FROM node:14.17.5-slim
+FROM node:16.9.1-slim
 
 COPY ./ ./
 

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно