Explorar o código

Merge pull request #26 from TechEmpower/master

aa
三刀 %!s(int64=2) %!d(string=hai) anos
pai
achega
c4f24811fe
Modificáronse 100 ficheiros con 1626 adicións e 2633 borrados
  1. 43 11
      frameworks/C++/treefrog/config/application.ini
  2. 10 0
      frameworks/C++/treefrog/config/cache.ini
  3. 1 1
      frameworks/C++/treefrog/controllers/worldcontroller.cpp
  4. 2 2
      frameworks/C++/treefrog/treefrog-epoll.dockerfile
  5. 2 2
      frameworks/C++/treefrog/treefrog-mongodb.dockerfile
  6. 2 2
      frameworks/C++/treefrog/treefrog-mysql.dockerfile
  7. 2 2
      frameworks/C++/treefrog/treefrog.dockerfile
  8. 42 0
      frameworks/C++/userver/README.md
  9. 53 0
      frameworks/C++/userver/benchmark_config.json
  10. 36 0
      frameworks/C++/userver/config.toml
  11. 21 0
      frameworks/C++/userver/userver-bare.dockerfile
  12. 21 0
      frameworks/C++/userver/userver.dockerfile
  13. 18 0
      frameworks/C++/userver/userver_benchmark/CMakeLists.txt
  14. 230 0
      frameworks/C++/userver/userver_benchmark/bare/simple_connection.cpp
  15. 27 0
      frameworks/C++/userver/userver_benchmark/bare/simple_connection.hpp
  16. 13 0
      frameworks/C++/userver/userver_benchmark/bare/simple_response.hpp
  17. 81 0
      frameworks/C++/userver/userver_benchmark/bare/simple_router.cpp
  18. 43 0
      frameworks/C++/userver/userver_benchmark/bare/simple_router.hpp
  19. 29 0
      frameworks/C++/userver/userver_benchmark/bare/simple_server.cpp
  20. 34 0
      frameworks/C++/userver/userver_benchmark/bare/simple_server.hpp
  21. 65 0
      frameworks/C++/userver/userver_benchmark/common/db_helpers.cpp
  22. 34 0
      frameworks/C++/userver/userver_benchmark/common/db_helpers.hpp
  23. 37 0
      frameworks/C++/userver/userver_benchmark/controllers/cached_queries/handler.cpp
  24. 29 0
      frameworks/C++/userver/userver_benchmark/controllers/cached_queries/handler.hpp
  25. 21 0
      frameworks/C++/userver/userver_benchmark/controllers/cached_queries/world_cache_component.cpp
  26. 36 0
      frameworks/C++/userver/userver_benchmark/controllers/cached_queries/world_cache_component.hpp
  27. 16 0
      frameworks/C++/userver/userver_benchmark/controllers/json/handler.cpp
  28. 21 0
      frameworks/C++/userver/userver_benchmark/controllers/json/handler.hpp
  29. 48 0
      frameworks/C++/userver/userver_benchmark/controllers/multiple_queries/handler.cpp
  30. 28 0
      frameworks/C++/userver/userver_benchmark/controllers/multiple_queries/handler.hpp
  31. 16 0
      frameworks/C++/userver/userver_benchmark/controllers/plaintext/handler.cpp
  32. 20 0
      frameworks/C++/userver/userver_benchmark/controllers/plaintext/handler.hpp
  33. 35 0
      frameworks/C++/userver/userver_benchmark/controllers/single_query/handler.cpp
  34. 27 0
      frameworks/C++/userver/userver_benchmark/controllers/single_query/handler.hpp
  35. 69 0
      frameworks/C++/userver/userver_benchmark/controllers/updates/handler.cpp
  36. 30 0
      frameworks/C++/userver/userver_benchmark/controllers/updates/handler.hpp
  37. 44 0
      frameworks/C++/userver/userver_benchmark/userver_techempower.cpp
  38. 53 0
      frameworks/C++/userver/userver_configs/dynamic_config_fallback.json
  39. 12 0
      frameworks/C++/userver/userver_configs/secure_data.json
  40. 99 0
      frameworks/C++/userver/userver_configs/static_config.yaml
  41. 1 1
      frameworks/C/h2o/h2o.sh
  42. 0 148
      frameworks/C/h2o/src/cache.c
  43. 0 51
      frameworks/C/h2o/src/cache.h
  44. 1 1
      frameworks/C/h2o/src/database.c
  45. 0 18
      frameworks/C/h2o/src/utility.c
  46. 1 4
      frameworks/C/h2o/src/utility.h
  47. 19 0
      frameworks/C/nginx/benchmark_config.json
  48. 7 0
      frameworks/C/nginx/nginx-njs.dockerfile
  49. 6 6
      frameworks/C/nginx/nginx.conf
  50. 2 7
      frameworks/C/nginx/nginx.dockerfile
  51. 11 0
      frameworks/C/nginx/njs/hello.js
  52. 49 0
      frameworks/C/nginx/njs/nginx.conf
  53. 2 2
      frameworks/CSharp/appmpower/appmpower-ado-pg.dockerfile
  54. 15 8
      frameworks/CSharp/appmpower/appmpower-odbc-my.dockerfile
  55. 8 5
      frameworks/CSharp/appmpower/appmpower-odbc-pg.dockerfile
  56. 2 2
      frameworks/CSharp/appmpower/appmpower.dockerfile
  57. 26 8
      frameworks/CSharp/appmpower/src/appMpower.ado
  58. 21 8
      frameworks/CSharp/appmpower/src/appMpower.csproj
  59. 0 38
      frameworks/CSharp/aspnetcore-corert/.gitignore
  60. 0 57
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/AsciiString.cs
  61. 0 19
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Caching.cs
  62. 0 57
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Fortunes.cs
  63. 0 295
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs
  64. 0 34
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Json.cs
  65. 0 46
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.MultipleQueries.cs
  66. 0 24
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs
  67. 0 45
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.SingleQuery.cs
  68. 0 45
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Updates.cs
  69. 0 197
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.cs
  70. 0 58
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkConfigurationHelpers.cs
  71. 0 62
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BufferExtensions.cs
  72. 0 141
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BufferWriter.cs
  73. 0 11
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Configuration/AppSettings.cs
  74. 0 12
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Configuration/DatabaseServer.cs
  75. 0 41
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/BatchUpdateString.cs
  76. 0 13
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/CachedWorld.cs
  77. 0 22
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Fortune.cs
  78. 0 9
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/JsonMessage.cs
  79. 0 272
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Providers/RawDbMySqlConnector.cs
  80. 0 265
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Providers/RawDbNpgsql.cs
  81. 0 29
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Random.cs
  82. 0 14
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/World.cs
  83. 0 65
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/DateHeader.cs
  84. 0 28
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/HttpApplication.cs
  85. 0 14
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/IHttpConnection.cs
  86. 0 8
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/NuGet.Config
  87. 0 40
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/PlatformBenchmarks.csproj
  88. 0 90
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Program.cs
  89. 0 11
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Startup.cs
  90. 0 57
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/StringBuilderCache.cs
  91. 0 3
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.json
  92. 0 4
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.mysql.json
  93. 0 4
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.postgresql.json
  94. 0 4
      frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.postgresql.updates.json
  95. 0 28
      frameworks/CSharp/aspnetcore-corert/README.md
  96. 0 16
      frameworks/CSharp/aspnetcore-corert/aspcore-corert.dockerfile
  97. 0 63
      frameworks/CSharp/aspnetcore-corert/benchmark_config.json
  98. 0 42
      frameworks/CSharp/aspnetcore-corert/config.toml
  99. 5 4
      frameworks/CSharp/aspnetcore/Benchmarks/Benchmarks.csproj
  100. 0 57
      frameworks/CSharp/aspnetcore/PlatformBenchmarks/AsciiString.cs

+ 43 - 11
frameworks/C++/treefrog/config/application.ini

@@ -34,12 +34,18 @@ UploadTemporaryDirectory=tmp
 # Specify setting files for SQL databases.
 SqlDatabaseSettingsFiles=database.ini
 
-# Specify the setting file for MongoDB, mongodb.ini.
+# Specify the setting file for MongoDB.
+# To access MongoDB server, uncomment the following line.
 MongoDbSettingsFile=mongodb.ini
 
-# Specify the setting file for Redis, redis.ini.
+# Specify the setting file for Redis.
+# To access Redis server, uncomment the following line.
 RedisSettingsFile=
 
+# Specify the setting file for Memcached.
+# To access Memcached server, uncomment the following line.
+MemcachedSettingsFile=
+
 # Specify the directory path to store SQL query files.
 SqlQueriesStoredDirectory=sql/
 
@@ -51,7 +57,24 @@ DirectViewRenderMode=false
 # Specify a file path for SQL query log.
 # If it's empty or the line is commented out, output to SQL query log
 # is disabled.
-SqlQueryLogFile=
+SqlQueryLog.FilePath=
+
+# Specify the layout of SQL query log.
+#  %d : date-time
+#  %p : priority (lowercase)
+#  %P : priority (uppercase)
+#  %t : thread ID (dec)
+#  %T : thread ID (hex)
+#  %i : PID (dec)
+#  %I : PID (hex)
+#  %e : elapsed processing time in milliseconds
+#  %m : log message
+#  %n : newline code
+SqlQueryLog.Layout="%d [%t] (%e) %m%n"
+
+# Specify the date-time format of SQL query log, see also QDateTime
+# class reference.
+SqlQueryLog.DateTimeFormat="yyyy-MM-dd hh:mm:ss"
 
 # Determines whether the application aborts (to create a core dump
 # on Unix systems) or not when it output a fatal message by tFatal()
@@ -95,6 +118,7 @@ Session.Name=TFSESSION
 # For 'sqlobject', the settings specified in SqlDatabaseSettingsFiles are used.
 # For 'mongodb', the settings specified in MongoDbSettingsFile are used.
 # For 'redis', the settings specified in RedisSettingsFile are used.
+# For 'memcached', the settings specified in MemcachedSettingsFile are used.
 Session.StoreType=cookie
 
 # Replaces the session ID with a new one each time one connects, and
@@ -111,6 +135,10 @@ Session.CookieDomain=
 # Specifies a path attribute to set in the session cookie. Defaults to /.
 Session.CookiePath=/
 
+# Specifies a value to assert that a cookie must not be sent with cross-origin
+# requests; Strict, Lax or None.
+Session.CookieSameSite=Lax
+
 # Probability that the garbage collection starts.
 # If 100 specified, the GC of sessions starts at the rate of once per 100
 # accesses. If 0 specified, the GC never starts.
@@ -182,6 +210,7 @@ AccessLog.FilePath=
 #  %r : First line of request
 #  %s : Status code
 #  %O : Bytes sent, including headers, cannot be zero
+#  %e : elapsed processing time in milliseconds
 #  %n : Newline code
 AccessLog.Layout="%h %d \"%r\" %s %O%n"
 
@@ -210,13 +239,13 @@ ActionMailer.smtp.HostName=
 # Specify the connection's port number.
 ActionMailer.smtp.Port=
 
-# Enables STARTTLS extension if true.
-ActionMailer.smtp.EnableSTARTTLS=false
-
 # Enables SMTP authentication if true; disables SMTP
 # authentication if false.
 ActionMailer.smtp.Authentication=false
 
+# Enables STARTTLS extension if true.
+ActionMailer.smtp.EnableSTARTTLS=false
+
 # Specify the user name for SMTP authentication.
 ActionMailer.smtp.UserName=
 
@@ -237,16 +266,19 @@ ActionMailer.smtp.DelayedDelivery=false
 ## Cache section
 ##
 
-# Specify the settings file to enable the cache module.
-# Comment out the following line.
+# Specify the settings file to enable the cache module,
+# which can be used through Tf::cache() function.
+# See https://api-reference.treefrogframework.org/classTCache.html.
+# Uncomment the following line and write connection information
+# to the file.
 Cache.SettingsFile=cache.ini
 
-# Specify the cache backend, such as 'sqlite', 'mongodb', 'redis' or
-# 'memory'.
+# Specify the cache backend, such as 'sqlite', 'mongodb', 'redis',
+# 'memcached' or 'memory'.
 Cache.Backend=memory
 
 # Probability of starting garbage collection (GC) for cache.
-# If 100 is specified, GC will be started at a rate of once per 100
+# If 1000 is specified, GC will be started at a rate of once per 1000
 # sets. If 0 is specified, the GC never starts.
 Cache.GcProbability=100000000
 

+ 10 - 0
frameworks/C++/treefrog/config/cache.ini

@@ -28,3 +28,13 @@ UserName=
 Password=
 ConnectOptions=
 PostOpenStatements=
+
+[memory]
+DatabaseName=tfcache.shm
+HostName=
+Port=
+UserName=
+Password=
+ConnectOptions=MEMORY_SIZE=1G
+PostOpenStatements=
+

+ 1 - 1
frameworks/C++/treefrog/controllers/worldcontroller.cpp

@@ -220,7 +220,7 @@ void WorldController::cached_pqueries()
 
 void WorldController::cached_pqueries(const QString &num)
 {
-    constexpr int SECONDS = 60 * 10;  // cache time
+    constexpr int SECONDS = 60 * 30;  // cache time
     QVariantList worlds;
     QVariantMap world;
     int d = std::min(std::max(num.toInt(), 1), 500);

+ 2 - 2
frameworks/C++/treefrog/treefrog-epoll.dockerfile

@@ -2,13 +2,13 @@ FROM buildpack-deps:jammy
 
 ENV DEBIAN_FRONTEND noninteractive
 ENV DEBCONF_NOWARNINGS yes
-ENV TFVER=2.5.0
+ENV TFVER=2.6.0
 
 RUN apt-get update -yqq && apt-get upgrade -yq && \
     apt-get install -yqq --no-install-recommends software-properties-common unzip wget libjemalloc-dev \
     qmake6 qt6-base-dev qt6-base-dev-tools qt6-tools-dev-tools qt6-declarative-dev libqt6sql6-mysql \
     libqt6sql6-psql libqt6sql6-odbc libqt6sql6-sqlite libqt6core6 libqt6qml6 libqt6xml6 libpq5 libodbc1 \
-    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config redis-server
+    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config
 RUN rm -f /usr/bin/qmake; ln -sf /usr/bin/qmake6 /usr/bin/qmake
 
 WORKDIR /usr/src

+ 2 - 2
frameworks/C++/treefrog/treefrog-mongodb.dockerfile

@@ -2,13 +2,13 @@ FROM buildpack-deps:jammy
 
 ENV DEBIAN_FRONTEND noninteractive
 ENV DEBCONF_NOWARNINGS yes
-ENV TFVER=2.5.0
+ENV TFVER=2.6.0
 
 RUN apt-get update -yqq && apt-get upgrade -yq && \
     apt-get install -yqq --no-install-recommends software-properties-common unzip wget libjemalloc-dev \
     qmake6 qt6-base-dev qt6-base-dev-tools qt6-tools-dev-tools qt6-declarative-dev libqt6sql6-mysql \
     libqt6sql6-psql libqt6sql6-odbc libqt6sql6-sqlite libqt6core6 libqt6qml6 libqt6xml6 libpq5 libodbc1 \
-    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config redis-server
+    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config
 RUN rm -f /usr/bin/qmake; ln -sf /usr/bin/qmake6 /usr/bin/qmake
 
 WORKDIR /usr/src

+ 2 - 2
frameworks/C++/treefrog/treefrog-mysql.dockerfile

@@ -2,13 +2,13 @@ FROM buildpack-deps:jammy
 
 ENV DEBIAN_FRONTEND noninteractive
 ENV DEBCONF_NOWARNINGS yes
-ENV TFVER=2.5.0
+ENV TFVER=2.6.0
 
 RUN apt-get update -yqq && apt-get upgrade -yq && \
     apt-get install -yqq --no-install-recommends software-properties-common unzip wget libjemalloc-dev \
     qmake6 qt6-base-dev qt6-base-dev-tools qt6-tools-dev-tools qt6-declarative-dev libqt6sql6-mysql \
     libqt6sql6-psql libqt6sql6-odbc libqt6sql6-sqlite libqt6core6 libqt6qml6 libqt6xml6 libpq5 libodbc1 \
-    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config redis-server
+    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config
 RUN rm -f /usr/bin/qmake; ln -sf /usr/bin/qmake6 /usr/bin/qmake
 
 WORKDIR /usr/src

+ 2 - 2
frameworks/C++/treefrog/treefrog.dockerfile

@@ -2,13 +2,13 @@ FROM buildpack-deps:jammy
 
 ENV DEBIAN_FRONTEND noninteractive
 ENV DEBCONF_NOWARNINGS yes
-ENV TFVER=2.5.0
+ENV TFVER=2.6.0
 
 RUN apt-get update -yqq && apt-get upgrade -yq && \
     apt-get install -yqq --no-install-recommends software-properties-common unzip wget libjemalloc-dev \
     qmake6 qt6-base-dev qt6-base-dev-tools qt6-tools-dev-tools qt6-declarative-dev libqt6sql6-mysql \
     libqt6sql6-psql libqt6sql6-odbc libqt6sql6-sqlite libqt6core6 libqt6qml6 libqt6xml6 libpq5 libodbc1 \
-    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config redis-server
+    libmongoc-dev libbson-dev gcc g++ clang make cmake pkg-config
 RUN rm -f /usr/bin/qmake; ln -sf /usr/bin/qmake6 /usr/bin/qmake
 
 WORKDIR /usr/src

+ 42 - 0
frameworks/C++/userver/README.md

@@ -0,0 +1,42 @@
+# userver Benchmarking Test
+
+This is the [userver](https://github.com/userver-framework/userver) portion of a [benchmarking test suite](https://github.com/TechEmpower/FrameworkBenchmarks) comparing a variety of web development platforms.
+
+This benchmarks comes in two configurations: **userver** and **userver-bare**, where both configurations use exactly the same handlers code, but **userver-bare** replaces default http implementation of **userver** with custom one.  
+You see, **userver** being feature-rich framework widely used in production comes with a lot of useful functionality built-in (metrics, dynamic configuring, logging/tracing, congestion control etc...) none of which is of any use in benchmarks; although most of that can be disabled via configs, some parts remain, and these parts aren't free.  
+The aim of **userver-bare** is to explore practical limits of lower-level **userver** functionality when performance is an absolute must, while still being idiomatic userver code.
+
+### Test Type Implementation Source Code
+
+* [Plaintext](userver_benchmark/controllers/plaintext/handler.cpp)
+* [Json](userver_benchmark/controllers/json/handler.cpp)
+* [Single Database Query](userver_benchmark/controllers/single_query/handler.cpp)
+* [Multiple Database Queries](userver_benchmark/controllers/multiple_queries/handler.cpp)
+* [Database Updates](userver_benchmark/controllers/updates/handler.cpp)
+* [Cached Queries](userver_benchmark/controllers/cached_queries/handler.cpp)
+
+## Test URLs
+### Plaintext
+
+http://localhost:8080/plaintext
+
+### Json
+
+http://localhost:8080/json
+
+### Single Database Query
+
+http://localhost:8080/db
+
+### Multiple Database Queries
+
+http://localhost:8080/queries
+
+### Database Updates
+
+http://localhost:8080/updates
+
+### Cached Queries
+
+http://localhost:8080/cached-queries
+

+ 53 - 0
frameworks/C++/userver/benchmark_config.json

@@ -0,0 +1,53 @@
+{
+  "framework": "userver",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "update_url": "/updates?queries=",
+        "cached_query_url": "/cached-queries?count=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "postgres",
+        "framework": "userver",
+        "language": "C++",
+        "flavor": "None",
+        "orm": "Micro",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "userver",
+        "notes": "",
+        "versus": "None"
+      },
+      "bare": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "update_url": "/updates?queries=",
+        "cached_query_url": "/cached-queries?count=",
+        "port": 8081,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "postgres",
+        "framework": "userver",
+        "language": "C++",
+        "flavor": "None",
+        "orm": "Micro",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "userver[bare]",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 36 - 0
frameworks/C++/userver/config.toml

@@ -0,0 +1,36 @@
+[framework]
+name = "userver"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.cached_query = "/cached-queries?count="
+approach = "Realistic"
+classification = "Fullstack"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Micro"
+platform = "None"
+webserver = "None"
+versus = "None"
+
+[bare]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.cached_query = "/cached-queries?count="
+approach = "Realistic"
+classification = "Micro"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Micro"
+platform = "None"
+webserver = "None"
+versus = "None"

+ 21 - 0
frameworks/C++/userver/userver-bare.dockerfile

@@ -0,0 +1,21 @@
+FROM ghcr.io/userver-framework/docker-userver-build-base:v1a AS builder
+WORKDIR /src
+RUN git clone https://github.com/userver-framework/userver.git && \
+    cd userver && git checkout b69a8db23844d3abbb68e40a502eae0ecd2e4b62
+COPY userver_benchmark/ ./
+RUN mkdir build && cd build && \
+    cmake -DUSERVER_IS_THE_ROOT_PROJECT=0 -DUSERVER_OPEN_SOURCE_BUILD=1 -DUSERVER_FEATURE_CRYPTOPP_BLAKE2=0 \
+          -DUSERVER_FEATURE_REDIS=0 -DUSERVER_FEATURE_CLICKHOUSE=0 -DUSERVER_FEATURE_MONGODB=0 -DUSERVER_FEATURE_RABBITMQ=0 -DUSERVER_FEATURE_GRPC=0 \
+          -DUSERVER_FEATURE_UTEST=0 \
+          -DUSERVER_FEATURE_POSTGRESQL=1 \
+          -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=native" .. && \
+    make -j $(nproc)
+
+FROM builder AS runner
+WORKDIR /app
+COPY userver_configs/* ./
+COPY --from=builder /src/build/userver_techempower ./
+
+EXPOSE 8081
+CMD ./userver_techempower -c ./static_config.yaml
+

+ 21 - 0
frameworks/C++/userver/userver.dockerfile

@@ -0,0 +1,21 @@
+FROM ghcr.io/userver-framework/docker-userver-build-base:v1a AS builder
+WORKDIR /src
+RUN git clone https://github.com/userver-framework/userver.git && \
+    cd userver && git checkout b69a8db23844d3abbb68e40a502eae0ecd2e4b62
+COPY userver_benchmark/ ./
+RUN mkdir build && cd build && \
+    cmake -DUSERVER_IS_THE_ROOT_PROJECT=0 -DUSERVER_OPEN_SOURCE_BUILD=1 -DUSERVER_FEATURE_CRYPTOPP_BLAKE2=0 \
+          -DUSERVER_FEATURE_REDIS=0 -DUSERVER_FEATURE_CLICKHOUSE=0 -DUSERVER_FEATURE_MONGODB=0 -DUSERVER_FEATURE_RABBITMQ=0 -DUSERVER_FEATURE_GRPC=0 \
+          -DUSERVER_FEATURE_UTEST=0 \
+          -DUSERVER_FEATURE_POSTGRESQL=1 \
+          -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=native" .. && \
+    make -j $(nproc)
+
+FROM builder AS runner
+WORKDIR /app
+COPY userver_configs/* ./
+COPY --from=builder /src/build/userver_techempower ./
+
+EXPOSE 8080
+CMD ./userver_techempower -c ./static_config.yaml
+

+ 18 - 0
frameworks/C++/userver/userver_benchmark/CMakeLists.txt

@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.12)
+project(userver_techempower CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+
+file(GLOB_RECURSE SOURCES
+  ${CMAKE_CURRENT_SOURCE_DIR}/controllers/*.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/common/*.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/bare/*.cpp
+)
+
+include(userver/cmake/SetupEnvironment.cmake)
+include(GNUInstallDirs)
+
+add_subdirectory(userver)
+
+add_executable(${PROJECT_NAME} ${SOURCES} userver_techempower.cpp)
+target_link_libraries(${PROJECT_NAME} PRIVATE userver-core userver-postgresql)

+ 230 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_connection.cpp

@@ -0,0 +1,230 @@
+#include "simple_connection.hpp"
+
+#include <array>
+
+#include <cctz/time_zone.h>
+#include <http_parser.h>
+#include <boost/container/small_vector.hpp>
+
+#include "simple_server.hpp"
+
+#include <userver/engine/async.hpp>
+#include <userver/utils/datetime/wall_coarse_clock.hpp>
+#include <userver/utils/scope_guard.hpp>
+
+namespace userver_techempower::bare {
+
+namespace {
+
+template <std::size_t N>
+class SmallString final {
+ public:
+  SmallString() = default;
+
+  void Append(const char* data, std::size_t length) {
+    const auto old_size = Size();
+    data_.resize(old_size + length);
+    std::memcpy(Data() + old_size, data, length);
+  }
+
+  void Append(std::string_view sw) { Append(sw.data(), sw.size()); }
+
+  [[nodiscard]] std::string_view AsSw() const { return {Data(), Size()}; }
+
+  [[nodiscard]] char* Data() { return data_.data(); }
+  [[nodiscard]] const char* Data() const { return data_.data(); }
+
+  [[nodiscard]] std::size_t Size() const { return data_.size(); }
+
+  void Clear() { data_.resize(0); }
+
+ private:
+  boost::container::small_vector<char, N> data_;
+};
+
+struct HttpParser final {
+  http_parser parser{};
+  http_parser_settings parser_settings{};
+
+  std::function<void(std::string_view)> on_request_cb{};
+
+  SmallString<50> url;
+
+  explicit HttpParser(std::function<void(std::string_view)> on_request_cb)
+      : on_request_cb{std::move(on_request_cb)} {
+    http_parser_init(&parser, HTTP_REQUEST);
+    parser.data = this;
+
+    http_parser_settings_init(&parser_settings);
+    parser_settings.on_url = HttpOnUrl;
+    parser_settings.on_message_begin = HttpOnMessageBegin;
+    parser_settings.on_message_complete = HttpOnMessageComplete;
+  }
+
+  void Execute(const char* data, std::size_t length) {
+    http_parser_execute(&parser, &parser_settings, data, length);
+  }
+
+  static int HttpOnUrl(http_parser* parser, const char* data,
+                       std::size_t length) {
+    auto* self = static_cast<HttpParser*>(parser->data);
+    self->url.Append(data, length);
+    return 0;
+  }
+
+  static int HttpOnMessageBegin(http_parser* parser) {
+    auto* self = static_cast<HttpParser*>(parser->data);
+    self->url.Clear();
+    return 0;
+  }
+
+  static int HttpOnMessageComplete(http_parser* parser) {
+    auto* self = static_cast<HttpParser*>(parser->data);
+    self->on_request_cb(self->url.AsSw());
+    return 0;
+  }
+};
+
+class ResponseBuffers final {
+ public:
+  using HeadersString = SmallString<200>;
+
+  HeadersString& Next(userver::engine::io::Socket& socket, std::string&& body) {
+    if (Size() == kMaxResponses) {
+      Send(socket);
+    }
+
+    auto& response = responses_.emplace_back();
+    response.body = std::move(body);
+    return response.headers;
+  }
+
+  void Send(userver::engine::io::Socket& socket) {
+    if (Size() == 0) {
+      return;
+    }
+
+    boost::container::small_vector<userver::engine::io::IoData,
+                                   kMaxResponses * 2>
+        iovec(Size() * 2);
+
+    std::size_t index = 0;
+    std::size_t total_size = 0;
+    for (const auto& response : responses_) {
+      iovec[index++] = {response.headers.Data(), response.headers.Size()};
+      iovec[index++] = {response.body.data(), response.body.size()};
+      total_size += response.headers.Size() + response.body.size();
+    }
+
+    if (socket.SendAll(iovec.data(), iovec.size(), {}) != total_size) {
+      throw std::runtime_error{"Socket closed by remote"};
+    }
+
+    responses_.clear();
+  }
+
+ private:
+  static constexpr std::size_t kMaxResponses = 16;
+
+  [[nodiscard]] std::size_t Size() const { return responses_.size(); }
+
+  struct Response final {
+    HeadersString headers;
+    std::string body;
+  };
+
+  boost::container::small_vector<Response, kMaxResponses> responses_;
+};
+
+constexpr std::string_view kCommonHeaders{"HTTP/1.1 200 OK\r\nServer: us\r\n"};
+constexpr std::string_view kHeadersEnd{"\r\n\r\n"};
+
+std::string MakeHttpDate(std::chrono::system_clock::time_point date) {
+  static const std::string kFormatString = "%a, %d %b %Y %H:%M:%S %Z";
+  static const auto tz = cctz::utc_time_zone();
+
+  return cctz::format(kFormatString, date, tz);
+}
+
+std::string_view GetCachedDate() {
+  constexpr size_t kMaxDateHeaderLength = 128;
+
+  static thread_local std::chrono::seconds::rep last_second = 0;
+  static thread_local char last_time_string[kMaxDateHeaderLength]{};
+  static thread_local std::string_view result_view{};
+
+  const auto now = userver::utils::datetime::WallCoarseClock::now();
+  const auto now_seconds =
+      std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch())
+          .count();
+  if (now_seconds != last_second) {
+    last_second = now_seconds;
+
+    const auto time_str = MakeHttpDate(now);
+
+    std::memcpy(last_time_string, time_str.c_str(), time_str.size());
+    result_view = std::string_view{last_time_string, time_str.size()};
+  }
+
+  return result_view;
+}
+
+}  // namespace
+
+SimpleConnection::SimpleConnection(SimpleServer& server,
+                                   userver::engine::io::Socket&& socket)
+    : server_{server},
+      socket_{std::move(socket)},
+      processing_task_{userver::engine::AsyncNoSpan([this] { Process(); })} {}
+
+SimpleConnection::~SimpleConnection() { processing_task_.SyncCancel(); }
+
+void SimpleConnection::Process() {
+  constexpr std::size_t kBufferSize = 4096;
+  std::array<char, kBufferSize> buffer{};
+
+  userver::utils::ScopeGuard close_guard{[this] { socket_.Close(); }};
+
+  ResponseBuffers buffers{};
+  const auto handle_request = [this, &buffers](std::string_view url) {
+    auto response = server_.HandleRequest(url);
+    const auto content_length_str = std::to_string(response.body.size());
+    auto& headers = buffers.Next(socket_, std::move(response.body));
+
+    headers.Append(kCommonHeaders);
+    headers.Append("Content-Type: ");
+    headers.Append(response.content_type);
+
+    headers.Append("\r\nContent-Length: ");
+    headers.Append(content_length_str);
+
+    headers.Append("\r\nDate: ");
+    headers.Append(GetCachedDate());
+
+    headers.Append(kHeadersEnd);
+  };
+  HttpParser parser{handle_request};
+
+  std::size_t last_bytes_read = 0;
+  while (true) {
+    bool is_readable = true;
+    if (last_bytes_read < kBufferSize) {
+      is_readable = socket_.WaitReadable({});
+    }
+
+    last_bytes_read =
+        is_readable ? socket_.RecvSome(buffer.data(), kBufferSize, {}) : 0;
+    if (last_bytes_read == 0) {
+      break;
+    }
+
+    parser.Execute(buffer.data(), last_bytes_read);
+    if (parser.parser.http_errno != 0) {
+      break;
+    }
+
+    buffers.Send(socket_);
+  }
+}
+
+}  // namespace userver_techempower::bare

+ 27 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_connection.hpp

@@ -0,0 +1,27 @@
+#pragma once
+
+#include <userver/engine/io/socket.hpp>
+#include <userver/engine/task/task_with_result.hpp>
+
+namespace userver_techempower::bare {
+
+class SimpleServer;
+
+class SimpleConnection final {
+ public:
+  explicit SimpleConnection(SimpleServer& server,
+                            userver::engine::io::Socket&& socket);
+  ~SimpleConnection();
+
+ private:
+  void Process();
+
+  const SimpleServer& server_;
+
+  userver::engine::io::Socket socket_;
+
+  userver::engine::TaskWithResult<void> processing_task_;
+};
+
+}  // namespace userver_techempower::bare
+

+ 13 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_response.hpp

@@ -0,0 +1,13 @@
+#pragma once
+
+#include <string>
+
+namespace userver_techempower::bare {
+
+struct SimpleResponse final {
+  std::string body;
+  std::string content_type;
+};
+
+}  // namespace userver_techempower::bare
+

+ 81 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_router.cpp

@@ -0,0 +1,81 @@
+#include "simple_router.hpp"
+
+#include <userver/components/component_context.hpp>
+
+#include "../controllers/cached_queries/handler.hpp"
+#include "../controllers/json/handler.hpp"
+#include "../controllers/multiple_queries/handler.hpp"
+#include "../controllers/plaintext/handler.hpp"
+#include "../controllers/single_query/handler.hpp"
+#include "../controllers/updates/handler.hpp"
+
+namespace userver_techempower::bare {
+
+namespace {
+
+constexpr std::string_view kPlainTextUrlPrefix{"/plaintext"};
+constexpr std::string_view kJsontUrlPrefix{"/json"};
+constexpr std::string_view kSingleQueryUrlPrefix{"/db"};
+constexpr std::string_view kMultipleQueriesUrlPrefix{"/queries"};
+constexpr std::string_view kUpdatesUrlPrefix{"/updates"};
+constexpr std::string_view kCachedQueriesUrlPrefix{"/cached-queries"};
+
+// NOLINTNEXTLINE
+const std::string kContentTypePlain{"text/plain"};
+// NOLINTNEXTLINE
+const std::string kContentTypeJson{"application/json"};
+
+bool StartsWith(std::string_view source, std::string_view pattern) {
+  return source.substr(0, pattern.length()) == pattern;
+}
+
+}  // namespace
+
+SimpleRouter::SimpleRouter(const userver::components::ComponentConfig& config,
+                           const userver::components::ComponentContext& context)
+    : userver::components::LoggableComponentBase{config, context},
+      single_query_{context.FindComponent<single_query::Handler>()},
+      multiple_queries_{context.FindComponent<multiple_queries::Handler>()},
+      updates_{context.FindComponent<updates::Handler>()},
+      cached_queries_{context.FindComponent<cached_queries::Handler>()} {}
+
+SimpleRouter::~SimpleRouter() = default;
+
+SimpleResponse SimpleRouter::RouteRequest(std::string_view url) const {
+  if (StartsWith(url, kPlainTextUrlPrefix)) {
+    return {plaintext::Handler::GetResponse(), kContentTypePlain};
+  }
+
+  if (StartsWith(url, kJsontUrlPrefix)) {
+    return {ToString(json::Handler::GetResponse()), kContentTypeJson};
+  }
+
+  if (StartsWith(url, kSingleQueryUrlPrefix)) {
+    return {ToString(single_query_.GetResponse()), kContentTypeJson};
+  }
+
+  if (StartsWith(url, kMultipleQueriesUrlPrefix)) {
+    const auto queries = db_helpers::ParseParamFromQuery(
+        url.substr(kMultipleQueriesUrlPrefix.size()), "queries");
+
+    return {ToString(multiple_queries_.GetResponse(queries)), kContentTypeJson};
+  }
+
+  if (StartsWith(url, kUpdatesUrlPrefix)) {
+    const auto queries = db_helpers::ParseParamFromQuery(
+        url.substr(kMultipleQueriesUrlPrefix.size()), "queries");
+
+    return {ToString(updates_.GetResponse(queries)), kContentTypeJson};
+  }
+
+  if (StartsWith(url, kCachedQueriesUrlPrefix)) {
+    const auto count = db_helpers::ParseParamFromQuery(
+        url.substr(kCachedQueriesUrlPrefix.size()), "count");
+
+    return {ToString(cached_queries_.GetResponse(count)), "application/json"};
+  }
+
+  throw std::runtime_error{"No handler found for url"};
+}
+
+}  // namespace userver_techempower::bare

+ 43 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_router.hpp

@@ -0,0 +1,43 @@
+#pragma once
+
+#include <userver/components/loggable_component_base.hpp>
+
+#include "simple_response.hpp"
+
+namespace userver_techempower {
+
+namespace single_query {
+class Handler;
+}
+namespace multiple_queries {
+class Handler;
+}
+namespace updates {
+class Handler;
+}
+namespace cached_queries {
+class Handler;
+}
+
+namespace bare {
+
+class SimpleRouter final : public userver::components::LoggableComponentBase {
+ public:
+  static constexpr std::string_view kName{"simple-router"};
+
+  SimpleRouter(const userver::components::ComponentConfig& config,
+               const userver::components::ComponentContext& context);
+  ~SimpleRouter() final;
+
+  [[nodiscard]] SimpleResponse RouteRequest(std::string_view url) const;
+
+ private:
+  const single_query::Handler& single_query_;
+  const multiple_queries::Handler& multiple_queries_;
+  const updates::Handler& updates_;
+  const cached_queries::Handler& cached_queries_;
+};
+
+}  // namespace bare
+}  // namespace userver_techempower
+

+ 29 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_server.cpp

@@ -0,0 +1,29 @@
+#include "simple_server.hpp"
+
+#include <userver/components/component_context.hpp>
+#include <userver/engine/io/socket.hpp>
+
+#include "simple_connection.hpp"
+#include "simple_router.hpp"
+
+namespace userver_techempower::bare {
+
+SimpleServer::SimpleServer(const userver::components::ComponentConfig& config,
+                           const userver::components::ComponentContext& context)
+    : userver::components::TcpAcceptorBase(config, context),
+      router_{context.FindComponent<SimpleRouter>()} {}
+
+SimpleServer::~SimpleServer() = default;
+
+void SimpleServer::ProcessSocket(userver::engine::io::Socket&& socket) {
+  const auto fd = socket.Fd();
+  connections_[fd] =
+      std::make_unique<SimpleConnection>(*this, std::move(socket));
+}
+
+SimpleResponse SimpleServer::HandleRequest(std::string_view url) const {
+  return router_.RouteRequest(url);
+}
+
+}  // namespace userver_techempower::bare
+

+ 34 - 0
frameworks/C++/userver/userver_benchmark/bare/simple_server.hpp

@@ -0,0 +1,34 @@
+#pragma once
+
+#include <array>
+#include <memory>
+
+#include <userver/components/tcp_acceptor_base.hpp>
+
+#include "simple_response.hpp"
+
+namespace userver_techempower::bare {
+
+class SimpleConnection;
+class SimpleRouter;
+
+class SimpleServer final : public userver::components::TcpAcceptorBase {
+ public:
+  static constexpr std::string_view kName{"simple-server"};
+
+  SimpleServer(const userver::components::ComponentConfig& config,
+               const userver::components::ComponentContext& context);
+  ~SimpleServer() final;
+
+ private:
+  void ProcessSocket(userver::engine::io::Socket&& socket) final;
+
+  friend class SimpleConnection;
+  [[nodiscard]] SimpleResponse HandleRequest(std::string_view url) const;
+
+  const SimpleRouter& router_;
+
+  static constexpr std::size_t kMaxFd = 65536;
+  std::array<std::unique_ptr<SimpleConnection>, kMaxFd> connections_;
+};
+}  // namespace userver_techempower::bare

+ 65 - 0
frameworks/C++/userver/userver_benchmark/common/db_helpers.cpp

@@ -0,0 +1,65 @@
+#include "db_helpers.hpp"
+
+#include <charconv>
+#include <cctype>
+
+#include <userver/formats/json/inline.hpp>
+#include <userver/utils/rand.hpp>
+
+namespace userver_techempower::db_helpers {
+
+namespace {
+
+int ParseFromQueryVal(std::string_view query_val) {
+  if (query_val.empty()) {
+    return 1;
+  }
+
+  int parse_result{};
+  const auto [ptr, err] = std::from_chars(query_val.data(), query_val.data() + query_val.size(), parse_result);
+  if (err != std::errc{} || ptr != query_val.data() + query_val.size()) {
+    return 1;
+  }
+
+  return std::min(500, std::max(1, parse_result));
+}
+
+}
+
+int GenerateRandomId() {
+  return userver::utils::RandRange(1, kMaxWorldRows + 1);
+}
+
+int GenerateRandomValue() {
+  return userver::utils::RandRange(1, kMaxWorldRows + 1);
+}
+
+userver::formats::json::Value Serialize(
+    const WorldTableRow& value,
+    userver::formats::serialize::To<userver::formats::json::Value>) {
+  return userver::formats::json::MakeObject("id", value.id, "randomNumber",
+                                            value.random_number);
+}
+
+int ParseParamFromQuery(const userver::server::http::HttpRequest& request,
+                        const std::string& name) {
+  const auto& arg_str = request.GetArg(name);
+  return ParseFromQueryVal(arg_str);
+}
+
+int ParseParamFromQuery(std::string_view url, std::string_view name) {
+  auto pos = url.find(name);
+  if (pos == std::string_view::npos) {
+    return 1;
+  }
+  pos += name.size() + 1; // +1 for '='
+
+  std::size_t len = 0;
+  while (pos + len < url.size() && std::isdigit(url[pos + len])) {
+    ++len;
+  }
+
+  return ParseFromQueryVal(url.substr(pos, len));
+}
+
+}  // namespace userver_techempower::db_helpers

+ 34 - 0
frameworks/C++/userver/userver_benchmark/common/db_helpers.hpp

@@ -0,0 +1,34 @@
+#pragma once
+
+#include <userver/formats/json/value.hpp>
+#include <userver/server/http/http_request.hpp>
+#include <userver/storages/postgres/cluster_types.hpp>
+#include <userver/storages/postgres/query.hpp>
+
+namespace userver_techempower::db_helpers {
+
+constexpr int kMaxWorldRows = 10000;
+const userver::storages::postgres::Query kSelectRowQuery{
+    "SELECT id, randomNumber FROM World WHERE id = $1"};
+constexpr auto kClusterHostType =
+    userver::storages::postgres::ClusterHostType::kMaster;
+constexpr std::string_view kDbComponentName = "hello-world-db";
+
+struct WorldTableRow final {
+  int id;
+  int random_number;
+};
+
+int GenerateRandomId();
+int GenerateRandomValue();
+
+userver::formats::json::Value Serialize(
+    const WorldTableRow& value,
+    userver::formats::serialize::To<userver::formats::json::Value>);
+
+int ParseParamFromQuery(const userver::server::http::HttpRequest& request,
+                        const std::string& name);
+
+int ParseParamFromQuery(std::string_view url, std::string_view name);
+
+}  // namespace userver_techempower::db_helpers

+ 37 - 0
frameworks/C++/userver/userver_benchmark/controllers/cached_queries/handler.cpp

@@ -0,0 +1,37 @@
+#include "handler.hpp"
+
+#include <userver/formats/serialize/common_containers.hpp>
+
+#include <boost/container/small_vector.hpp>
+
+namespace userver_techempower::cached_queries {
+
+Handler::Handler(const userver::components::ComponentConfig& config,
+                 const userver::components::ComponentContext& context)
+    : userver::server::handlers::HttpHandlerJsonBase{config, context},
+      cache_{context.FindComponent<WorldCacheComponent>()},
+      query_arg_name_{"count"} {}
+
+userver::formats::json::Value Handler::HandleRequestJsonThrow(
+    const userver::server::http::HttpRequest& request,
+    const userver::formats::json::Value&,
+    userver::server::request::RequestContext&) const {
+  const auto queries =
+      db_helpers::ParseParamFromQuery(request, query_arg_name_);
+
+  return GetResponse(queries);
+}
+
+userver::formats::json::Value Handler::GetResponse(int queries) const {
+  boost::container::small_vector<db_helpers::WorldTableRow, 500> result(
+      queries);
+
+  const auto cache_ptr = cache_.Get();
+  const auto& cache = *cache_ptr;
+  std::generate(result.begin(), result.end(),
+                [&cache] { return cache.at(db_helpers::GenerateRandomId()); });
+
+  return userver::formats::json::ValueBuilder{result}.ExtractValue();
+}
+
+}  // namespace userver_techempower::cached_queries

+ 29 - 0
frameworks/C++/userver/userver_benchmark/controllers/cached_queries/handler.hpp

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <userver/server/handlers/http_handler_json_base.hpp>
+
+#include "world_cache_component.hpp"
+
+namespace userver_techempower::cached_queries {
+
+class Handler final : public userver::server::handlers::HttpHandlerJsonBase {
+ public:
+  static constexpr std::string_view kName = "cached-queries-handler";
+
+  Handler(const userver::components::ComponentConfig& config,
+          const userver::components::ComponentContext& context);
+
+  userver::formats::json::Value HandleRequestJsonThrow(
+      const userver::server::http::HttpRequest& request,
+      const userver::formats::json::Value&,
+      userver::server::request::RequestContext&) const final;
+
+  userver::formats::json::Value GetResponse(int queries) const;
+
+ private:
+  const WorldCacheComponent& cache_;
+
+  const std::string query_arg_name_;
+};
+
+}  // namespace userver_techempower::cached_queries

+ 21 - 0
frameworks/C++/userver/userver_benchmark/controllers/cached_queries/world_cache_component.cpp

@@ -0,0 +1,21 @@
+#include "world_cache_component.hpp"
+
+namespace userver_techempower::cached_queries {
+
+WorldCache::WorldCache() { data_.reserve(db_helpers::kMaxWorldRows + 1); }
+
+std::size_t WorldCache::size() const { return data_.size(); }
+
+void WorldCache::insert_or_assign(int key, db_helpers::WorldTableRow&& row) {
+  if (size() <= static_cast<std::size_t>(key)) {
+    data_.resize(key + 1);
+  }
+
+  data_[key] = row;
+}
+
+const db_helpers::WorldTableRow& WorldCache::at(size_t ind) const {
+  return data_[ind];
+}
+
+}  // namespace userver_techempower::cached_queries

+ 36 - 0
frameworks/C++/userver/userver_benchmark/controllers/cached_queries/world_cache_component.hpp

@@ -0,0 +1,36 @@
+#pragma once
+
+#include <vector>
+
+#include "../../common/db_helpers.hpp"
+
+#include <userver/cache/base_postgres_cache.hpp>
+
+namespace userver_techempower::cached_queries {
+
+class WorldCache final {
+ public:
+  WorldCache();
+
+  std::size_t size() const;
+  void insert_or_assign(int key, db_helpers::WorldTableRow&& row);
+
+  const db_helpers::WorldTableRow& at(size_t ind) const;
+
+ private:
+  std::vector<db_helpers::WorldTableRow> data_;
+};
+
+struct WorldCachePolicy final {
+  static constexpr std::string_view kName = "world-pg-cache";
+  using ValueType = db_helpers::WorldTableRow;
+  using CacheContainer = WorldCache;
+  static constexpr auto kKeyMember = &db_helpers::WorldTableRow::id;
+  static constexpr const char* kQuery = "SELECT id, randomNumber FROM World";
+  static constexpr const char* kUpdatedField = "";
+  static constexpr auto kClusterHostType = db_helpers::kClusterHostType;
+};
+
+using WorldCacheComponent = userver::components::PostgreCache<WorldCachePolicy>;
+
+}  // namespace userver_techempower::cached_queries

+ 16 - 0
frameworks/C++/userver/userver_benchmark/controllers/json/handler.cpp

@@ -0,0 +1,16 @@
+#include "handler.hpp"
+
+namespace userver_techempower::json {
+
+userver::formats::json::Value Handler::HandleRequestJsonThrow(
+    const userver::server::http::HttpRequest&,
+    const userver::formats::json::Value&,
+    userver::server::request::RequestContext&) const {
+  return GetResponse();
+}
+
+userver::formats::json::Value Handler::GetResponse() {
+  return userver::formats::json::MakeObject("message", "Hello, World!");
+}
+
+}  // namespace userver_techempower::json

+ 21 - 0
frameworks/C++/userver/userver_benchmark/controllers/json/handler.hpp

@@ -0,0 +1,21 @@
+#pragma once
+
+#include <userver/server/handlers/http_handler_json_base.hpp>
+
+namespace userver_techempower::json {
+
+class Handler final : public userver::server::handlers::HttpHandlerJsonBase {
+ public:
+  static constexpr std::string_view kName = "json-handler";
+
+  using HttpHandlerJsonBase::HttpHandlerJsonBase;
+
+  userver::formats::json::Value HandleRequestJsonThrow(
+      const userver::server::http::HttpRequest&,
+      const userver::formats::json::Value&,
+      userver::server::request::RequestContext&) const final;
+
+  static userver::formats::json::Value GetResponse();
+};
+
+}  // namespace userver_techempower::json

+ 48 - 0
frameworks/C++/userver/userver_benchmark/controllers/multiple_queries/handler.cpp

@@ -0,0 +1,48 @@
+#include "handler.hpp"
+
+#include "../../common/db_helpers.hpp"
+
+#include <userver/components/component_context.hpp>
+#include <userver/formats/serialize/common_containers.hpp>
+#include <userver/storages/postgres/postgres.hpp>
+
+#include <boost/container/small_vector.hpp>
+
+namespace userver_techempower::multiple_queries {
+
+Handler::Handler(const userver::components::ComponentConfig& config,
+                 const userver::components::ComponentContext& context)
+    : userver::server::handlers::HttpHandlerJsonBase{config, context},
+      pg_{context
+              .FindComponent<userver::components::Postgres>(
+                  db_helpers::kDbComponentName)
+              .GetCluster()},
+      query_arg_name_{"queries"} {}
+
+userver::formats::json::Value Handler::HandleRequestJsonThrow(
+    const userver::server::http::HttpRequest& request,
+    const userver::formats::json::Value&,
+    userver::server::request::RequestContext&) const {
+  const auto queries =
+      db_helpers::ParseParamFromQuery(request, query_arg_name_);
+
+  return GetResponse(queries);
+}
+
+userver::formats::json::Value Handler::GetResponse(int queries) const {
+  boost::container::small_vector<int, 500> random_ids(queries);
+  std::generate(random_ids.begin(), random_ids.end(),
+                db_helpers::GenerateRandomId);
+
+  boost::container::small_vector<db_helpers::WorldTableRow, 500> result{};
+  for (auto id : random_ids) {
+    result.push_back(pg_->Execute(db_helpers::kClusterHostType,
+                                  db_helpers::kSelectRowQuery, id)
+                         .AsSingleRow<db_helpers::WorldTableRow>(
+                             userver::storages::postgres::kRowTag));
+  }
+
+  return userver::formats::json::ValueBuilder{result}.ExtractValue();
+}
+
+}  // namespace userver_techempower::multiple_queries

+ 28 - 0
frameworks/C++/userver/userver_benchmark/controllers/multiple_queries/handler.hpp

@@ -0,0 +1,28 @@
+#pragma once
+
+#include <userver/server/handlers/http_handler_json_base.hpp>
+#include <userver/storages/postgres/postgres_fwd.hpp>
+
+namespace userver_techempower::multiple_queries {
+
+class Handler final : public userver::server::handlers::HttpHandlerJsonBase {
+ public:
+  static constexpr std::string_view kName = "multiple-queries-handler";
+
+  Handler(const userver::components::ComponentConfig& config,
+          const userver::components::ComponentContext& context);
+
+  userver::formats::json::Value HandleRequestJsonThrow(
+      const userver::server::http::HttpRequest& request,
+      const userver::formats::json::Value&,
+      userver::server::request::RequestContext&) const final;
+
+  userver::formats::json::Value GetResponse(int queries) const;
+
+ private:
+  const userver::storages::postgres::ClusterPtr pg_;
+
+  const std::string query_arg_name_;
+};
+
+}  // namespace userver_techempower::multiple_queries

+ 16 - 0
frameworks/C++/userver/userver_benchmark/controllers/plaintext/handler.cpp

@@ -0,0 +1,16 @@
+#include "handler.hpp"
+
+namespace userver_techempower::plaintext {
+
+std::string Handler::HandleRequestThrow(
+    const userver::server::http::HttpRequest& request,
+    userver::server::request::RequestContext&) const {
+  request.GetHttpResponse().SetContentType("text/plain");
+  return GetResponse();
+}
+
+std::string Handler::GetResponse() {
+  return "Hello, World!";
+}
+
+}  // namespace userver_techempower::plaintext

+ 20 - 0
frameworks/C++/userver/userver_benchmark/controllers/plaintext/handler.hpp

@@ -0,0 +1,20 @@
+#pragma once
+
+#include <userver/server/handlers/http_handler_base.hpp>
+
+namespace userver_techempower::plaintext {
+
+class Handler final : public userver::server::handlers::HttpHandlerBase {
+ public:
+  static constexpr std::string_view kName = "plaintext-handler";
+
+  using HttpHandlerBase::HttpHandlerBase;
+
+  std::string HandleRequestThrow(
+      const userver::server::http::HttpRequest& request,
+      userver::server::request::RequestContext&) const final;
+
+  static std::string GetResponse();
+};
+
+}  // namespace userver_techempower::plaintext

+ 35 - 0
frameworks/C++/userver/userver_benchmark/controllers/single_query/handler.cpp

@@ -0,0 +1,35 @@
+#include "handler.hpp"
+
+#include "../../common/db_helpers.hpp"
+
+#include <userver/components/component_context.hpp>
+#include <userver/storages/postgres/postgres.hpp>
+
+namespace userver_techempower::single_query {
+
+Handler::Handler(const userver::components::ComponentConfig& config,
+                 const userver::components::ComponentContext& context)
+    : userver::server::handlers::HttpHandlerJsonBase{config, context},
+      pg_{context
+              .FindComponent<userver::components::Postgres>(
+                  db_helpers::kDbComponentName)
+              .GetCluster()} {}
+
+userver::formats::json::Value Handler::HandleRequestJsonThrow(
+    const userver::server::http::HttpRequest&,
+    const userver::formats::json::Value&,
+    userver::server::request::RequestContext&) const {
+  return GetResponse();
+}
+
+userver::formats::json::Value Handler::GetResponse() const {
+  const auto row =
+      pg_->Execute(db_helpers::kClusterHostType, db_helpers::kSelectRowQuery,
+                   db_helpers::GenerateRandomId())
+          .AsSingleRow<db_helpers::WorldTableRow>(
+              userver::storages::postgres::kRowTag);
+
+  return db_helpers::Serialize(row, {});
+}
+
+}  // namespace userver_techempower::single_query

+ 27 - 0
frameworks/C++/userver/userver_benchmark/controllers/single_query/handler.hpp

@@ -0,0 +1,27 @@
+#pragma once
+
+#include <userver/server/handlers/http_handler_json_base.hpp>
+
+#include <userver/storages/postgres/postgres_fwd.hpp>
+
+namespace userver_techempower::single_query {
+
+class Handler final : public userver::server::handlers::HttpHandlerJsonBase {
+ public:
+  static constexpr std::string_view kName = "single-query-handler";
+
+  Handler(const userver::components::ComponentConfig& config,
+          const userver::components::ComponentContext& context);
+
+  userver::formats::json::Value HandleRequestJsonThrow(
+      const userver::server::http::HttpRequest&,
+      const userver::formats::json::Value&,
+      userver::server::request::RequestContext&) const final;
+
+  userver::formats::json::Value GetResponse() const;
+
+ private:
+  const userver::storages::postgres::ClusterPtr pg_;
+};
+
+}  // namespace userver_techempower::single_query

+ 69 - 0
frameworks/C++/userver/userver_benchmark/controllers/updates/handler.cpp

@@ -0,0 +1,69 @@
+#include "handler.hpp"
+
+#include "../../common/db_helpers.hpp"
+
+#include <userver/components/component_context.hpp>
+#include <userver/formats/serialize/common_containers.hpp>
+#include <userver/storages/postgres/postgres.hpp>
+
+#include <boost/container/small_vector.hpp>
+
+namespace userver_techempower::updates {
+
+namespace {
+
+constexpr const char* kUpdateQueryStr{R"(
+UPDATE World w SET
+  randomNumber = new_numbers.randomNumber
+FROM ( SELECT
+  UNNEST($1) as id,
+  UNNEST($2) as randomNumber
+) new_numbers
+WHERE w.id = new_numbers.id
+)"};
+
+}
+
+Handler::Handler(const userver::components::ComponentConfig& config,
+                 const userver::components::ComponentContext& context)
+    : userver::server::handlers::HttpHandlerJsonBase{config, context},
+      pg_{context.FindComponent<userver::components::Postgres>("hello-world-db")
+              .GetCluster()},
+      query_arg_name_{"queries"},
+      update_query_{kUpdateQueryStr} {}
+
+userver::formats::json::Value Handler::HandleRequestJsonThrow(
+    const userver::server::http::HttpRequest& request,
+    const userver::formats::json::Value&,
+    userver::server::request::RequestContext&) const {
+  const auto queries =
+      db_helpers::ParseParamFromQuery(request, query_arg_name_);
+
+  return GetResponse(queries);
+}
+
+userver::formats::json::Value Handler::GetResponse(int queries) const {
+  std::vector<int> random_ids(queries);
+  std::generate(random_ids.begin(), random_ids.end(),
+                db_helpers::GenerateRandomId);
+  std::sort(random_ids.begin(), random_ids.end());
+
+  boost::container::small_vector<db_helpers::WorldTableRow, 500> result{};
+  for (auto id : random_ids) {
+    result.push_back(pg_->Execute(db_helpers::kClusterHostType,
+                                  db_helpers::kSelectRowQuery, id)
+                         .AsSingleRow<db_helpers::WorldTableRow>(
+                             userver::storages::postgres::kRowTag));
+  }
+
+  std::vector<int> random_numbers(queries);
+  std::generate(random_numbers.begin(), random_numbers.end(),
+                db_helpers::GenerateRandomValue);
+
+  pg_->Execute(db_helpers::kClusterHostType, update_query_, random_ids,
+               random_numbers);
+
+  return userver::formats::json::ValueBuilder{result}.ExtractValue();
+}
+
+}  // namespace userver_techempower::updates

+ 30 - 0
frameworks/C++/userver/userver_benchmark/controllers/updates/handler.hpp

@@ -0,0 +1,30 @@
+#pragma once
+
+#include <userver/server/handlers/http_handler_json_base.hpp>
+#include <userver/storages/postgres/postgres_fwd.hpp>
+#include <userver/storages/postgres/query.hpp>
+
+namespace userver_techempower::updates {
+
+class Handler final : public userver::server::handlers::HttpHandlerJsonBase {
+ public:
+  static constexpr std::string_view kName = "updates-handler";
+
+  Handler(const userver::components::ComponentConfig& config,
+          const userver::components::ComponentContext& context);
+
+  userver::formats::json::Value HandleRequestJsonThrow(
+      const userver::server::http::HttpRequest& request,
+      const userver::formats::json::Value&,
+      userver::server::request::RequestContext&) const final;
+
+  userver::formats::json::Value GetResponse(int queries) const;
+
+ private:
+  const userver::storages::postgres::ClusterPtr pg_;
+
+  const std::string query_arg_name_;
+  const userver::storages::postgres::Query update_query_;
+};
+
+}  // namespace userver_techempower::updates

+ 44 - 0
frameworks/C++/userver/userver_benchmark/userver_techempower.cpp

@@ -0,0 +1,44 @@
+#include <userver/components/minimal_server_component_list.hpp>
+#include <userver/testsuite/testsuite_support.hpp>
+#include <userver/utils/daemon_run.hpp>
+
+#include <userver/storages/postgres/component.hpp>
+#include <userver/storages/secdist/component.hpp>
+
+#include "controllers/cached_queries/handler.hpp"
+#include "controllers/json/handler.hpp"
+#include "controllers/multiple_queries/handler.hpp"
+#include "controllers/plaintext/handler.hpp"
+#include "controllers/single_query/handler.hpp"
+#include "controllers/updates/handler.hpp"
+
+#include "bare/simple_router.hpp"
+#include "bare/simple_server.hpp"
+
+namespace userver_techempower {
+
+int Main(int argc, char* argv[]) {
+  auto component_list =
+      userver::components::MinimalServerComponentList()
+          .Append<userver::components::Secdist>()
+          .Append<userver::components::TestsuiteSupport>()
+          .Append<userver::components::Postgres>("hello-world-db")
+          .Append<plaintext::Handler>()
+          .Append<json::Handler>()
+          .Append<single_query::Handler>()
+          .Append<multiple_queries::Handler>()
+          .Append<updates::Handler>()
+          .Append<cached_queries::WorldCacheComponent>()
+          .Append<cached_queries::Handler>()
+          // bare
+          .Append<bare::SimpleRouter>()
+          .Append<bare::SimpleServer>();
+
+  return userver::utils::DaemonMain(argc, argv, component_list);
+}
+
+}  // namespace userver_techempower
+
+int main(int argc, char* argv[]) {
+  return userver_techempower::Main(argc, argv);
+}

+ 53 - 0
frameworks/C++/userver/userver_configs/dynamic_config_fallback.json

@@ -0,0 +1,53 @@
+{
+  "USERVER_CACHES": {},
+  "USERVER_CANCEL_HANDLE_REQUEST_BY_DEADLINE": false,
+  "USERVER_CHECK_AUTH_IN_HANDLERS": false,
+  "USERVER_DUMPS": {},
+  "USERVER_HTTP_PROXY": "",
+  "USERVER_LOG_REQUEST": false,
+  "USERVER_LOG_REQUEST_HEADERS": false,
+  "USERVER_LRU_CACHES": {},
+  "USERVER_RPS_CCONTROL_CUSTOM_STATUS": {},
+  "USERVER_TASK_PROCESSOR_PROFILER_DEBUG": {},
+  "HTTP_CLIENT_CONNECTION_POOL_SIZE": 1000,
+  "HTTP_CLIENT_CONNECT_THROTTLE": {
+    "http-limit": 6000,
+    "http-per-second": 1500,
+    "https-limit": 100,
+    "https-per-second": 25,
+    "per-host-limit": 3000,
+    "per-host-per-second": 500
+  },
+  "HTTP_CLIENT_ENFORCE_TASK_DEADLINE": {
+    "cancel-request": false,
+    "update-timeout": false
+  },
+  "USERVER_TASK_PROCESSOR_QOS": {
+    "default-service": {
+      "default-task-processor": {
+        "wait_queue_overload": {
+          "action": "ignore",
+          "length_limit": 16385,
+          "time_limit_us": 30000
+        }
+      }
+    }
+  },
+
+  "POSTGRES_STATEMENT_METRICS_SETTINGS": {},
+  "POSTGRES_CONNECTION_PIPELINE_ENABLED": false,
+  "POSTGRES_CONNECTION_POOL_SETTINGS": {
+    "hello_world": {
+      "min_pool_size": 28,
+      "max_pool_size": 28,
+      "max_queue_size": 512
+    }
+  },
+  "POSTGRES_CONNECTION_SETTINGS": {},
+  "POSTGRES_DEFAULT_COMMAND_CONTROL": {
+    "network_timeout_ms": 7000,
+    "statement_timeout_ms": 7000
+  },
+  "POSTGRES_HANDLERS_COMMAND_CONTROL": {},
+  "POSTGRES_QUERIES_COMMAND_CONTROL": {}
+}

+ 12 - 0
frameworks/C++/userver/userver_configs/secure_data.json

@@ -0,0 +1,12 @@
+{
+  "postgresql_settings": {
+    "databases": {
+      "hello_world": [{
+        "shard_number" : 0,
+        "hosts": [
+          "postgresql://benchmarkdbuser:benchmarkdbpass@tfb-database:5432/hello_world?sslmode=disable"
+        ]
+      }]
+    }
+  }
+}

+ 99 - 0
frameworks/C++/userver/userver_configs/static_config.yaml

@@ -0,0 +1,99 @@
+# yaml
+components_manager:
+    event_thread_pool:
+        threads: 3
+    coro_pool:
+        initial_size: 10000             # Preallocate 10000 coroutines at startup.
+        max_size: 65536                 # Do not keep more than 65536 preallocated coroutines.
+        stack_size: 66560               # 64Kb for coroutine stack
+
+    task_processors:                    # Task processor is an executor for coroutine tasks
+
+        main-task-processor:            # Make a task processor for CPU-bound couroutine tasks.
+            thread_name: main-worker    # OS will show the threads of this task processor with 'main-worker' prefix.
+            worker_threads: 25
+            guess-cpu-limit: true
+
+        fs-task-processor:              # Make a separate task processor for filesystem bound tasks.
+            thread_name: fs-worker
+            worker_threads: 4
+
+    default_task_processor: main-task-processor
+
+    components:                         # Configuring components that were registered via component_list
+        server:
+            listener:                   # configuring the main listening socket...
+                port: 8080              # ...to listen on this port and...
+                task_processor: main-task-processor    # ...process incoming requests on this task processor.
+                handler-defaults:
+                    set_tracing_headers: false
+            server-name: us
+        simple-router:
+        simple-server:
+            port: 8081
+            task_processor: main-task-processor
+        logging:
+            fs-task-processor: fs-task-processor
+            loggers:
+                default:
+                    file_path: '@stderr'
+                    level: ERROR
+                    overflow_behavior: discard  # Drop logs if the system is too busy to write them down.
+
+        tracer:                                 # Component that helps to trace execution times and requests in logs.
+            service-name: userver-techempower   # "You know. You all know exactly who I am. Say my name. " (c)
+
+        dynamic-config:                      # Dynamic config storage options, do nothing
+            fs-cache-path: ''
+        dynamic-config-fallbacks:            # Load options from file and push them into the dynamic config storage.
+            fallback-path: /app/dynamic_config_fallback.json
+
+        testsuite-support:
+
+        secdist: # Component that stores configuration of hosts and passwords
+            config: /app/secure_data.json  # Values are supposed to be stored in this file
+            missing-ok: false                             # ... but if the file is missing it is still ok
+
+        plaintext-handler:
+            path: /plaintext
+            method: GET
+            task_processor: main-task-processor
+
+        json-handler:
+            path: /json
+            method: GET
+            task_processor: main-task-processor
+
+        hello-world-db:
+            dbalias: hello_world
+            blocking_task_processor: fs-task-processor
+            min_pool_size: 28
+            max_pool_size: 28
+            max_queue_size: 512
+
+        single-query-handler:
+            path: /db
+            method: GET
+            task_processor: main-task-processor
+
+        multiple-queries-handler:
+            path: /queries
+            method: GET
+            task_processor: main-task-processor
+
+        updates-handler:
+            path: /updates
+            method: GET
+            task_processor: main-task-processor
+
+        world-pg-cache:
+            pgcomponent: hello-world-db
+            update-types: only-full
+            update-interval: 1s
+            update-correction: 50ms
+
+        cached-queries-handler:
+            path: /cached-queries
+            method: GET
+            task_processor: main-task-processor
+

+ 1 - 1
frameworks/C/h2o/h2o.sh

@@ -49,7 +49,7 @@ run_curl()
 run_h2o_app()
 {
 	LD_LIBRARY_PATH="${MUSTACHE_C_PREFIX}/lib:$LD_LIBRARY_PATH" \
-	taskset -c "$1" "$2/h2o_app" -a20 -f "$3/template" -m "$DB_CONN" "$4" "$5" \
+	taskset -c "$1" "$2/h2o_app" -a20 -e32 -f "$3/template" -m "$DB_CONN" "$4" "$5" \
 	        -d "host=$DBHOST dbname=hello_world user=benchmarkdbuser sslmode=disable \
 	            password=benchmarkdbpass" &
 }

+ 0 - 148
frameworks/C/h2o/src/cache.c

@@ -1,148 +0,0 @@
-/*
- Copyright (c) 2018 Anton Valentinov Kirilov
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- associated documentation files (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge, publish, distribute,
- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
- OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <h2o/cache.h>
-
-#include "cache.h"
-#include "error.h"
-#include "utility.h"
-
-// Increasing the number of caches by the following factor reduces contention; must be a power of 2.
-#define CONCURRENCY_FACTOR 4
-
-static size_t get_index(size_t n, h2o_cache_hashcode_t keyhash)
-{
-	assert(is_power_of_2(n));
-	return keyhash & (n - 1);
-}
-
-int cache_create(size_t concurrency,
-                 size_t capacity,
-                 uint64_t duration,
-                 void (*destroy_cb)(h2o_iovec_t value),
-                 cache_t *cache)
-{
-	memset(cache, 0, sizeof(*cache));
-	assert(is_power_of_2(CONCURRENCY_FACTOR));
-	// Rounding up to a power of 2 simplifies the calculations a little bit, and, as any increase in
-	// the number of caches, potentially reduces thread contention.
-	cache->cache_num = CONCURRENCY_FACTOR * round_up_to_power_of_2(concurrency);
-	cache->cache_num = MAX(cache->cache_num, 1);
-	capacity = (capacity + cache->cache_num - 1) / cache->cache_num;
-	cache->cache = malloc(cache->cache_num * sizeof(*cache->cache));
-
-	if (!cache->cache)
-		return 1;
-
-	cache->cache_lock = malloc(cache->cache_num * sizeof(*cache->cache_lock));
-
-	if (!cache->cache_lock)
-		goto error;
-
-	for (size_t i = 0; i < cache->cache_num; i++) {
-		cache->cache[i] = h2o_cache_create(0, capacity, duration, destroy_cb);
-
-		if (!cache->cache[i] || pthread_spin_init(cache->cache_lock + i, PTHREAD_PROCESS_PRIVATE)) {
-			if (cache->cache[i])
-				h2o_cache_destroy(cache->cache[i]);
-
-			cache->cache_num = i;
-			cache_destroy(cache);
-			return 1;
-		}
-	}
-
-	return 0;
-error:
-	free(cache->cache);
-	return 1;
-}
-
-void cache_destroy(cache_t *cache)
-{
-	if (cache->cache) {
-		assert(cache->cache_lock);
-
-		for (size_t i = 0; i < cache->cache_num; i++) {
-			h2o_cache_destroy(cache->cache[i]);
-			pthread_spin_destroy(cache->cache_lock + i);
-		}
-
-		free(cache->cache);
-		free((void *) cache->cache_lock);
-		cache->cache = NULL;
-		cache->cache_lock = NULL;
-	}
-	else
-		assert(!cache->cache_lock);
-}
-
-h2o_cache_ref_t *cache_fetch(cache_t *cache,
-                             uint64_t now,
-                             h2o_iovec_t key,
-                             h2o_cache_hashcode_t keyhash)
-{
-	if (!keyhash)
-		keyhash = h2o_cache_calchash(key.base, key.len);
-
-	const size_t idx = get_index(cache->cache_num, keyhash);
-	pthread_spinlock_t * const lock = cache->cache_lock + idx;
-
-	CHECK_ERROR(pthread_spin_lock, lock);
-
-	h2o_cache_ref_t * const ret = h2o_cache_fetch(cache->cache[idx], now, key, keyhash);
-
-	CHECK_ERROR(pthread_spin_unlock, lock);
-	return ret;
-}
-
-void cache_release(cache_t *cache, h2o_cache_ref_t *ref, h2o_cache_hashcode_t keyhash)
-{
-	if (!keyhash)
-		keyhash = h2o_cache_calchash(ref->key.base, ref->key.len);
-
-	const size_t idx = get_index(cache->cache_num, keyhash);
-
-	h2o_cache_release(cache->cache[idx], ref);
-}
-
-int cache_set(uint64_t now,
-              h2o_iovec_t key,
-              h2o_cache_hashcode_t keyhash,
-              h2o_iovec_t value,
-              cache_t *cache)
-{
-	if (!keyhash)
-		keyhash = h2o_cache_calchash(key.base, key.len);
-
-	const size_t idx = get_index(cache->cache_num, keyhash);
-	pthread_spinlock_t * const lock = cache->cache_lock + idx;
-
-	CHECK_ERROR(pthread_spin_lock, lock);
-
-	const int ret = h2o_cache_set(cache->cache[idx], now, key, keyhash, value);
-
-	CHECK_ERROR(pthread_spin_unlock, lock);
-	return ret;
-}

+ 0 - 51
frameworks/C/h2o/src/cache.h

@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2018 Anton Valentinov Kirilov
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- associated documentation files (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge, publish, distribute,
- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
- OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef CACHE_H_
-
-#define CACHE_H_
-
-#include <pthread.h>
-#include <stdint.h>
-#include <h2o/cache.h>
-
-typedef struct {
-	h2o_cache_t **cache;
-	pthread_spinlock_t *cache_lock;
-	size_t cache_num;
-} cache_t;
-
-int cache_create(size_t concurrency,
-                 size_t capacity,
-                 uint64_t duration,
-                 void (*destroy_cb)(h2o_iovec_t value),
-                 cache_t *cache);
-void cache_destroy(cache_t *cache);
-h2o_cache_ref_t *cache_fetch(cache_t *cache,
-                             uint64_t now,
-                             h2o_iovec_t key,
-                             h2o_cache_hashcode_t keyhash);
-void cache_release(cache_t *cache, h2o_cache_ref_t *ref, h2o_cache_hashcode_t keyhash);
-int cache_set(uint64_t now,
-              h2o_iovec_t key,
-              h2o_cache_hashcode_t keyhash,
-              h2o_iovec_t value,
-              cache_t *cache);
-
-#endif // CACHE_H_

+ 1 - 1
frameworks/C/h2o/src/database.c

@@ -218,7 +218,7 @@ static void on_database_connect_read_ready(h2o_socket_t *sock, const char *err)
 		return;
 	}
 	else if (send_status) {
-		h2o_socket_notify_write(conn->sock, on_database_write_ready);
+		h2o_socket_notify_write(conn->sock, on_database_connect_write_ready);
 		return;
 	}
 

+ 0 - 18
frameworks/C/h2o/src/utility.c

@@ -220,24 +220,6 @@ uint32_t get_random_number(uint32_t max_rand, unsigned int *seed)
 	return ret / bucket_size;
 }
 
-bool is_power_of_2(size_t x)
-{
-	return !!x & !(x & (x - 1));
-}
-
-size_t round_up_to_power_of_2(size_t x)
-{
-	static_assert(sizeof(size_t) == sizeof(unsigned long),
-	              "The size_t type must have the same size as unsigned long.");
-
-	size_t ret = (SIZE_MAX ^ SIZE_MAX >> 1) >> __builtin_clzl(x);
-
-	if (x - ret)
-		ret <<= 1;
-
-	return ret;
-}
-
 // merge sort
 list_t *sort_list(list_t *head, int (*compare)(const list_t *, const list_t *))
 {

+ 1 - 4
frameworks/C/h2o/src/utility.h

@@ -33,8 +33,7 @@
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
 // mainly used to silence compiler warnings about unused function parameters
 #define IGNORE_FUNCTION_PARAMETER(p) ((void) (p))
-// Do not use the following MAX and MIN macros with parameters that have side effects.
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
+// Do not use the following MIN macro with parameters that have side effects.
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 #define TOSTRING(x) # x
 #define MKSTR(x) TOSTRING(x)
@@ -50,8 +49,6 @@ yajl_gen_status gen_integer(long long number, char *buf, size_t len, yajl_gen ge
 json_generator_t *get_json_generator(list_t **pool, size_t *gen_num);
 size_t get_maximum_cache_line_size(void);
 uint32_t get_random_number(uint32_t max_rand, unsigned int *seed);
-bool is_power_of_2(size_t x);
-size_t round_up_to_power_of_2(size_t x);
 // stable sort
 list_t *sort_list(list_t *head, int (*compare)(const list_t *, const list_t *));
 

+ 19 - 0
frameworks/C/nginx/benchmark_config.json

@@ -19,6 +19,25 @@
         "display_name": "Nginx",
         "notes": "",
         "versus": ""
+      },
+      "njs": {
+        "plaintext_url": "/plaintext",
+        "json_url": "/json",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Platform",
+        "framework": "njs",
+        "language": "C",
+        "flavor": "Njs",
+        "orm": "Raw",
+        "platform": "None",
+        "database": "none",
+        "webserver": "nginx",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Nginx-njs",
+        "notes": "",
+        "versus": "nginx"
       }
     }
   ]

+ 7 - 0
frameworks/C/nginx/nginx-njs.dockerfile

@@ -0,0 +1,7 @@
+FROM nginx:mainline
+
+ADD ./ ./
+
+EXPOSE 8080
+
+CMD ["nginx", "-c", "/njs/nginx.conf"]

+ 6 - 6
frameworks/C/nginx/nginx.conf

@@ -1,5 +1,5 @@
 user www-data;
-worker_processes  auto;
+worker_processes auto;
 worker_cpu_affinity auto;
 error_log stderr error;
 #worker_rlimit_nofile 1024000;
@@ -8,11 +8,11 @@ daemon off;
 
 events {
     worker_connections 32768;
-	multi_accept off; #default
+    multi_accept off; #default
 }
 
 http {
-    include       /etc/nginx/mime.types;
+    include /etc/nginx/mime.types;
     access_log off;
     server_tokens off;
     msie_padding off;
@@ -25,10 +25,10 @@ http {
     keepalive_requests 300000; #default 100
 
     server {
-        listen      8080 default_server reuseport deferred fastopen=4096;
-                    #8080 default_server reuseport deferred backlog=65535 fastopen=4096;
+        listen 8080 default_server reuseport deferred fastopen=4096;
+        #8080 default_server reuseport deferred backlog=65535 fastopen=4096;
         root /;
-        
+
         location = /plaintext {
             default_type text/plain;
             return 200 "Hello, World!";

+ 2 - 7
frameworks/C/nginx/nginx.dockerfile

@@ -1,12 +1,7 @@
-FROM ubuntu:22.04
-
-ARG DEBIAN_FRONTEND=noninteractive
-
-RUN apt-get update -yqq
-RUN apt-get install -y nginx-light
+FROM nginx:mainline
 
 ADD ./ ./
 
 EXPOSE 8080
 
-CMD nginx -c /nginx.conf
+CMD ["nginx", "-c", "/nginx.conf"]

+ 11 - 0
frameworks/C/nginx/njs/hello.js

@@ -0,0 +1,11 @@
+function hello(r) {
+  r.headersOut["Content-Type"] = "text/plain; charset=UTF-8";
+  r.return(200, "Hello, World!");
+}
+
+function json(r) {
+  r.headersOut["Content-Type"] = "application/json";
+  r.return(200, JSON.stringify({ message: "Hello, World!" }));
+}
+
+export default { hello, json };

+ 49 - 0
frameworks/C/nginx/njs/nginx.conf

@@ -0,0 +1,49 @@
+worker_processes auto;
+worker_cpu_affinity auto;
+error_log stderr error;
+#worker_rlimit_nofile 1024000;
+timer_resolution 1s;
+daemon off;
+
+load_module modules/ngx_http_js_module.so;
+
+events {
+   worker_connections 32768;
+   multi_accept off; #default
+}
+
+http {
+   include /etc/nginx/mime.types;
+   access_log off;
+   server_tokens off;
+   msie_padding off;
+
+   sendfile off; #default
+   tcp_nopush off; #default
+   tcp_nodelay on; #default
+   keepalive_timeout 65;
+   keepalive_disable none; #default msie6
+   keepalive_requests 300000; #default 100
+
+   js_path "/etc/nginx/njs/";
+
+   #js_import utils.js;
+   js_import main from /njs/hello.js;
+
+   server {
+      listen 8080 default_server reuseport deferred fastopen=4096;
+      #8080 default_server reuseport deferred backlog=65535 fastopen=4096;
+
+      location = /plaintext {
+         js_content main.hello;
+      }
+
+      location = /json {
+         js_content main.json;
+      }
+
+      #location = /version {
+      #   js_content utils.version;
+      #}
+   }
+}

+ 2 - 2
frameworks/CSharp/appmpower/appmpower-ado-pg.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:6.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
 RUN apt-get update
 RUN apt-get -yqq install clang zlib1g-dev libkrb5-dev libtinfo5
 
@@ -8,7 +8,7 @@ RUN mv ./appMpower.ado ./appMpower.csproj
 RUN dotnet publish -c Release -o out -r linux-x64
 
 # Construct the actual image that will run
-FROM mcr.microsoft.com/dotnet/aspnet:6.0.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
 RUN apt-get update
 
 WORKDIR /app

+ 15 - 8
frameworks/CSharp/appmpower/appmpower-odbc-my.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:6.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
 RUN apt-get update
 RUN apt-get -yqq install clang zlib1g-dev libkrb5-dev libtinfo5
 RUN apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
@@ -7,10 +7,13 @@ RUN apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
 
 WORKDIR /odbc
 
-RUN curl -L -o unixODBC-2.3.9.tar.gz ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz
-RUN tar -xvf unixODBC-2.3.9.tar.gz
+#RUN curl -L -o unixODBC-2.3.9.tar.gz ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz
+RUN curl -L -o unixODBC-2.3.11.tar.gz ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.11.tar.gz
+#RUN tar -xvf unixODBC-2.3.9.tar.gz
+RUN tar -xvf unixODBC-2.3.11.tar.gz
 
-WORKDIR /odbc/unixODBC-2.3.9
+#WORKDIR /odbc/unixODBC-2.3.9
+WORKDIR /odbc/unixODBC-2.3.11
 RUN ./configure --prefix=/usr/local/unixODBC
 RUN make
 RUN make install
@@ -22,7 +25,7 @@ COPY src .
 RUN dotnet publish -c Release -o out -r linux-x64 /p:Database=mysql
 
 # Construct the actual image that will run
-FROM mcr.microsoft.com/dotnet/aspnet:6.0.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
 
 RUN apt-get update
 # The following installs standard versions unixodbc 2.3.6 and pgsqlodbc 11
@@ -32,9 +35,13 @@ RUN apt-get install -y unixodbc wget curl
 
 WORKDIR /odbc
 
-RUN curl -L -o mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64.tar.gz https://downloads.mariadb.com/Connectors/odbc/connector-odbc-3.1.14/mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64.tar.gz
-RUN tar -xvzf mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64.tar.gz
-RUN cp mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64/lib/mariadb/libm* /usr/lib/
+#RUN curl -L -o mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64.tar.gz https://downloads.mariadb.com/Connectors/odbc/connector-odbc-3.1.14/mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64.tar.gz
+RUN curl -L -o mariadb-connector-odbc-3.1.17-debian-bullseye-amd64.tar.gz https://downloads.mariadb.com/Connectors/odbc/connector-odbc-3.1.17/mariadb-connector-odbc-3.1.17-debian-bullseye-amd64.tar.gz
+
+#RUN tar -xvzf mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64.tar.gz
+#RUN cp mariadb-connector-odbc-3.1.14-debian-9-stretch-amd64/lib/mariadb/libm* /usr/lib/
+RUN tar -xvzf mariadb-connector-odbc-3.1.17-debian-bullseye-amd64.tar.gz
+RUN cp mariadb-connector-odbc-3.1.17-debian-bullseye-amd64/lib/mariadb/libm* /usr/lib/
 
 COPY --from=build /usr/local/unixODBC /usr/local/unixODBC
 

+ 8 - 5
frameworks/CSharp/appmpower/appmpower-odbc-pg.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:6.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
 RUN apt-get update
 RUN apt-get -yqq install clang zlib1g-dev libkrb5-dev libtinfo5
 RUN apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
@@ -9,11 +9,13 @@ WORKDIR /odbc
 
 # To compile the latest postgresql odbc driver, postgresql itself needs to be installed
 #RUN curl -L -o postgresql-14.1.tar.gz https://ftp.postgresql.org/pub/source/v14.1/postgresql-14.1.tar.gz
-RUN curl -L -o unixODBC-2.3.9.tar.gz ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz
+#RUN curl -L -o unixODBC-2.3.9.tar.gz ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz
+RUN curl -L -o unixODBC-2.3.11.tar.gz ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.11.tar.gz
 #RUN curl -L -o psqlodbc-13.02.0000.tar.gz https://ftp.postgresql.org/pub/odbc/versions/src/psqlodbc-13.02.0000.tar.gz
 
 #RUN tar -xvf postgresql-14.1.tar.gz
-RUN tar -xvf unixODBC-2.3.9.tar.gz
+#RUN tar -xvf unixODBC-2.3.9.tar.gz
+RUN tar -xvf unixODBC-2.3.11.tar.gz
 #RUN tar -xvf psqlodbc-13.02.0000.tar.gz
 
 #WORKDIR /odbc/postgresql-14.1
@@ -23,7 +25,8 @@ RUN tar -xvf unixODBC-2.3.9.tar.gz
 
 #ENV PATH=/usr/local/pgsql/bin:$PATH
 
-WORKDIR /odbc/unixODBC-2.3.9
+#WORKDIR /odbc/unixODBC-2.3.9
+WORKDIR /odbc/unixODBC-2.3.11
 RUN ./configure --prefix=/usr/local/unixODBC
 RUN make
 RUN make install
@@ -40,7 +43,7 @@ COPY src .
 RUN dotnet publish -c Release -o out -r linux-x64  /p:Database=postgresql
 
 # Construct the actual image that will run
-FROM mcr.microsoft.com/dotnet/aspnet:6.0.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
 
 RUN apt-get update
 # The following installs standard versions unixodbc 2.3.6 and pgsqlodbc 11

+ 2 - 2
frameworks/CSharp/appmpower/appmpower.dockerfile

@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:6.0.100 AS build
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
 RUN apt-get update
 RUN apt-get -yqq install clang zlib1g-dev libkrb5-dev libtinfo5
 
@@ -7,7 +7,7 @@ COPY src .
 RUN dotnet publish -c Release -o out -r linux-x64
 
 # Construct the actual image that will run
-FROM mcr.microsoft.com/dotnet/aspnet:6.0.0 AS runtime
+FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
 RUN apt-get update
 
 WORKDIR /app

+ 26 - 8
frameworks/CSharp/appmpower/src/appMpower.ado

@@ -1,26 +1,44 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
    <PropertyGroup>
-      <TargetFramework>net6.0</TargetFramework>
+      <TargetFramework>net7.0</TargetFramework>
       <OutputType>Exe</OutputType>
       <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 
-      <TrimmerDefaultAction>link</TrimmerDefaultAction>
+      <!-- Normal .NET 7 -->
+      <PublishAot>true</PublishAot>
+      <SelfContained>true</SelfContained>
+      <InvariantGlobalization>true</InvariantGlobalization>
+      <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
       <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
-      <IlcPgoOptimize>true</IlcPgoOptimize>
+      <DebugType>none</DebugType>
+      <GenerateRuntimeConfigurationFiles>false</GenerateRuntimeConfigurationFiles>
+
+      <!-- Only some may work - From the experimental AOT version -->
+      <IlcFoldIdenticalMethodBodies>true</IlcFoldIdenticalMethodBodies>
       <IlcTrimMetadata>true</IlcTrimMetadata>
+      <IlcInvariantGlobalization>true</IlcInvariantGlobalization>
+      <IlcGenerateCompleteTypeMetadata>false</IlcGenerateCompleteTypeMetadata>
+
+      <SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
 
+      <!--
+      <TrimMode>link</TrimMode>
+      -->
+
+      <!-- Opt out of the "easy mode" of the CoreRT compiler (http://aka.ms/OptimizeCoreRT) -->
+      <IlcPgoOptimize>true</IlcPgoOptimize>
+
+      <!-- This benchmark is marked Stripped, so we might as well do this: -->
       <UseSystemResourceKeys>true</UseSystemResourceKeys>
       <EventSourceSupport>false</EventSourceSupport>
       <DebuggerSupport>false</DebuggerSupport>
-      <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
    </PropertyGroup>
 
    <ItemGroup>
-      <PackageReference Include="Npgsql" Version="6.0.5" />
-      <PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
-      <PackageReference Include="System.Data.Odbc" Version="6.0.0" />
-      <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
+      <PackageReference Include="Npgsql" Version="7.0.0" />
+      <PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
+      <PackageReference Include="System.Data.Odbc" Version="7.0.0" />
    </ItemGroup>
 
    <PropertyGroup>

+ 21 - 8
frameworks/CSharp/appmpower/src/appMpower.csproj

@@ -1,35 +1,48 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <OutputType>Exe</OutputType>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 
     <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
-    <SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
+
+    <!-- Normal .NET 7 -->
+    <PublishAot>true</PublishAot>
+    <SelfContained>true</SelfContained>
     <InvariantGlobalization>true</InvariantGlobalization>
+    <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
+    <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
+    <DebugType>none</DebugType>
+    <GenerateRuntimeConfigurationFiles>false</GenerateRuntimeConfigurationFiles>
+
+    <!-- Only some may work - From the experimental AOT version -->
+    <IlcFoldIdenticalMethodBodies>true</IlcFoldIdenticalMethodBodies>
+    <IlcTrimMetadata>true</IlcTrimMetadata>
+    <IlcInvariantGlobalization>true</IlcInvariantGlobalization>
+    <IlcGenerateCompleteTypeMetadata>false</IlcGenerateCompleteTypeMetadata>
+
+    <!-- Still works from the experimental AOT version, but high risk -->
     <IlcDisableReflection>true</IlcDisableReflection>
 
+    <SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
+
     <!--
     <TrimMode>link</TrimMode>
     -->
 
     <!-- Opt out of the "easy mode" of the CoreRT compiler (http://aka.ms/OptimizeCoreRT) -->
-    <TrimmerDefaultAction>link</TrimmerDefaultAction>
-    <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
     <IlcPgoOptimize>true</IlcPgoOptimize>
-    <IlcTrimMetadata>true</IlcTrimMetadata>
 
     <!-- This benchmark is marked Stripped, so we might as well do this: -->
     <UseSystemResourceKeys>true</UseSystemResourceKeys>
     <EventSourceSupport>false</EventSourceSupport>
     <DebuggerSupport>false</DebuggerSupport>
-    <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
+
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.Data.Odbc" Version="6.0.0" />
-    <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
+    <PackageReference Include="System.Data.Odbc" Version="7.0.0" />
   </ItemGroup>
 
   <PropertyGroup>

+ 0 - 38
frameworks/CSharp/aspnetcore-corert/.gitignore

@@ -1,38 +0,0 @@
-[Oo]bj/
-[Bb]in/
-[Oo]ut/
-TestResults/
-.nuget/
-*.sln.ide/
-_ReSharper.*/
-.idea/
-packages/
-artifacts/
-PublishProfiles/
-.vs/
-*.user
-*.suo
-*.cache
-*.docstates
-_ReSharper.*
-nuget.exe
-*net45.csproj
-*net451.csproj
-*k10.csproj
-*.psess
-*.vsp
-*.pidb
-*.userprefs
-*DS_Store
-*.ncrunchsolution
-*.*sdf
-*.ipch
-*.swp
-*~
-.build/
-.testPublish/
-launchSettings.json
-BenchmarkDotNet.Artifacts/
-BDN.Generated/
-binaries/
-global.json

+ 0 - 57
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/AsciiString.cs

@@ -1,57 +0,0 @@
-// 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.Text;
-
-namespace PlatformBenchmarks;
-
-public readonly struct AsciiString : IEquatable<AsciiString>
-{
-    private readonly byte[] _data;
-
-    public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s);
-
-    private AsciiString(byte[] b) => _data = b;
-
-    public int Length => _data.Length;
-
-    public ReadOnlySpan<byte> AsSpan() => _data;
-
-    public static implicit operator ReadOnlySpan<byte>(AsciiString str) => str._data;
-    public static implicit operator byte[](AsciiString str) => str._data;
-
-    public static implicit operator AsciiString(string str) => new(str);
-
-    public override string ToString() => Encoding.ASCII.GetString(_data);
-    public static explicit operator string(AsciiString str) => str.ToString();
-
-    public bool Equals(AsciiString other) => ReferenceEquals(_data, other._data) || SequenceEqual(_data, other._data);
-    private bool SequenceEqual(byte[] data1, byte[] data2) => new Span<byte>(data1).SequenceEqual(data2);
-
-    public static bool operator ==(AsciiString a, AsciiString b) => a.Equals(b);
-    public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b);
-    public override bool Equals(object other) => (other is AsciiString @string) && Equals(@string);
-
-    public static AsciiString operator +(AsciiString a, AsciiString b)
-    {
-        var result = new byte[a.Length + b.Length];
-        a._data.CopyTo(result, 0);
-        b._data.CopyTo(result, a.Length);
-        return new AsciiString(result);
-    }
-
-    public override int GetHashCode()
-    {
-        // Copied from x64 version of string.GetLegacyNonRandomizedHashCode()
-        // https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/String.Comparison.cs
-        var data = _data;
-        int hash1 = 5381;
-        int hash2 = hash1;
-        foreach (int b in data)
-        {
-            hash1 = ((hash1 << 5) + hash1) ^ b;
-        }
-        return hash1 + (hash2 * 1566083941);
-    }
-
-}

+ 0 - 19
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Caching.cs

@@ -1,19 +0,0 @@
-// 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.
-
-#if DATABASE
-
-using System.IO.Pipelines;
-using System.Threading.Tasks;
-
-namespace PlatformBenchmarks;
-
-public partial class BenchmarkApplication
-{
-    private async Task Caching(PipeWriter pipeWriter, int count)
-    {
-        OutputMultipleQueries(pipeWriter, await Db.LoadCachedQueries(count), SerializerContext.CachedWorldArray);
-    }
-}
-
-#endif

+ 0 - 57
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Fortunes.cs

@@ -1,57 +0,0 @@
-// 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.
-
-#if DATABASE
-
-using System.Collections.Generic;
-using System.IO.Pipelines;
-using System.Text.Encodings.Web;
-using System.Threading.Tasks;
-
-namespace PlatformBenchmarks
-{
-    public partial class BenchmarkApplication
-    {
-        private readonly static AsciiString _fortunesPreamble =
-            _http11OK +
-            _headerServer + _crlf +
-            _headerContentTypeHtml + _crlf +
-            _headerContentLength;
-
-        private async Task Fortunes(PipeWriter pipeWriter)
-        {
-            OutputFortunes(pipeWriter, await Db.LoadFortunesRows());
-        }
-
-        private void OutputFortunes(PipeWriter pipeWriter, List<Fortune> model)
-        {
-            var writer = GetWriter(pipeWriter, sizeHint: 1600); // in reality it's 1361
-
-            writer.Write(_fortunesPreamble);
-
-            var lengthWriter = writer;
-            writer.Write(_contentLengthGap);
-
-            // Date header
-            writer.Write(DateHeader.HeaderBytes);
-
-            var bodyStart = writer.Buffered;
-            // Body
-            writer.Write(_fortunesTableStart);
-            foreach (var item in model)
-            {
-                writer.Write(_fortunesRowStart);
-                writer.WriteNumeric((uint)item.Id);
-                writer.Write(_fortunesColumn);
-                writer.WriteUtf8String(HtmlEncoder.Encode(item.Message));
-                writer.Write(_fortunesRowEnd);
-            }
-            writer.Write(_fortunesTableEnd);
-            lengthWriter.WriteNumeric((uint)(writer.Buffered - bodyStart));
-
-            writer.Commit();
-        }
-    }
-}
-
-#endif

+ 0 - 295
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.HttpConnection.cs

@@ -1,295 +0,0 @@
-// 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.Buffers;
-using System.IO.Pipelines;
-using System.Runtime.CompilerServices;
-using System.Text.Encodings.Web;
-using System.Text.Unicode;
-using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
-
-namespace PlatformBenchmarks;
-
-public partial class BenchmarkApplication : IHttpConnection
-{
-    private State _state;
-
-    public PipeReader Reader { get; set; }
-    public PipeWriter Writer { get; set; }
-
-    protected HtmlEncoder HtmlEncoder { get; } = CreateHtmlEncoder();
-
-    private HttpParser<ParsingAdapter> Parser { get; } = new HttpParser<ParsingAdapter>();
-
-    public async Task ExecuteAsync()
-    {
-        try
-        {
-            await ProcessRequestsAsync();
-
-            Reader.Complete();
-        }
-        catch (Exception ex)
-        {
-            Reader.Complete(ex);
-        }
-        finally
-        {
-            Writer.Complete();
-        }
-    }
-
-    private static HtmlEncoder CreateHtmlEncoder()
-    {
-        var settings = new TextEncoderSettings(UnicodeRanges.BasicLatin, UnicodeRanges.Katakana, UnicodeRanges.Hiragana);
-        settings.AllowCharacter('\u2014');  // allow EM DASH through
-        return HtmlEncoder.Create(settings);
-    }
-
-#if !DATABASE
-    private async Task ProcessRequestsAsync()
-    {
-        while (true)
-        {
-            var readResult = await Reader.ReadAsync(default);
-            var buffer = readResult.Buffer;
-            var isCompleted = readResult.IsCompleted;
-
-            if (buffer.IsEmpty && isCompleted)
-            {
-                return;
-            }
-
-            if (!HandleRequests(buffer, isCompleted))
-            {
-                return;
-            }
-
-            await Writer.FlushAsync(default);
-        }
-    }
-
-    private bool HandleRequests(in ReadOnlySequence<byte> buffer, bool isCompleted)
-    {
-        var reader = new SequenceReader<byte>(buffer);
-        var writer = GetWriter(Writer, sizeHint: 160 * 16); // 160*16 is for Plaintext, for Json 160 would be enough
-
-        while (true)
-        {
-            if (!ParseHttpRequest(ref reader, isCompleted))
-            {
-                return false;
-            }
-
-            if (_state == State.Body)
-            {
-                ProcessRequest(ref writer);
-
-                _state = State.StartLine;
-
-                if (!reader.End)
-                {
-                    // More input data to parse
-                    continue;
-                }
-            }
-
-            // No more input or incomplete data, Advance the Reader
-            Reader.AdvanceTo(reader.Position, buffer.End);
-            break;
-        }
-
-        writer.Commit();
-        return true;
-    }
-
-    private bool ParseHttpRequest(ref SequenceReader<byte> reader, bool isCompleted)
-    {
-        var state = _state;
-
-        if (state == State.StartLine)
-        {
-            if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
-            {
-                state = State.Headers;
-            }
-        }
-
-        if (state == State.Headers)
-        {
-            var success = Parser.ParseHeaders(new ParsingAdapter(this), ref reader);
-
-            if (success)
-            {
-                state = State.Body;
-            }
-        }
-
-        if (state != State.Body && isCompleted)
-        {
-            ThrowUnexpectedEndOfData();
-        }
-
-        _state = state;
-        return true;
-    }
-#else
-        private async Task ProcessRequestsAsync()
-        {
-            while (true)
-            {
-                var readResult = await Reader.ReadAsync();
-                var buffer = readResult.Buffer;
-                var isCompleted = readResult.IsCompleted;
-
-                if (buffer.IsEmpty && isCompleted)
-                {
-                    return;
-                }
-
-                while (true)
-                {
-                    if (!ParseHttpRequest(ref buffer, isCompleted))
-                    {
-                        return;
-                    }
-
-                    if (_state == State.Body)
-                    {
-                        await ProcessRequestAsync();
-
-                        _state = State.StartLine;
-
-                        if (!buffer.IsEmpty)
-                        {
-                            // More input data to parse
-                            continue;
-                        }
-                    }
-
-                    // No more input or incomplete data, Advance the Reader
-                    Reader.AdvanceTo(buffer.Start, buffer.End);
-                    break;
-                }
-
-                await Writer.FlushAsync();
-            }
-        }
-
-        private bool ParseHttpRequest(ref ReadOnlySequence<byte> buffer, bool isCompleted)
-        {
-            var reader = new SequenceReader<byte>(buffer);
-            var state = _state;
-
-            if (state == State.StartLine)
-            {
-                if (Parser.ParseRequestLine(new ParsingAdapter(this), ref reader))
-                {
-                    state = State.Headers;
-                }
-            }
-
-            if (state == State.Headers)
-            {
-                var success = Parser.ParseHeaders(new ParsingAdapter(this), ref reader);
-
-                if (success)
-                {
-                    state = State.Body;
-                }
-            }
-
-            if (state != State.Body && isCompleted)
-            {
-                ThrowUnexpectedEndOfData();
-            }
-
-            _state = state;
-
-            if (state == State.Body)
-            {
-                // Complete request read, consumed and examined are the same (length 0)
-                buffer = buffer.Slice(reader.Position, 0);
-            }
-            else
-            {
-                // In-complete request read, consumed is current position and examined is the remaining.
-                buffer = buffer.Slice(reader.Position);
-            }
-
-            return true;
-        }
-#endif
-
-    public void OnStaticIndexedHeader(int index)
-    {
-    }
-
-    public void OnStaticIndexedHeader(int index, ReadOnlySpan<byte> value)
-    {
-    }
-
-    public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
-    {
-    }
-
-    public void OnHeadersComplete(bool endStream)
-    {
-    }
-
-    private static void ThrowUnexpectedEndOfData()
-    {
-        throw new InvalidOperationException("Unexpected end of data!");
-    }
-
-    private enum State
-    {
-        StartLine,
-        Headers,
-        Body
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private static BufferWriter<WriterAdapter> GetWriter(PipeWriter pipeWriter, int sizeHint)
-        => new(new WriterAdapter(pipeWriter), sizeHint);
-
-    private struct WriterAdapter : IBufferWriter<byte>
-    {
-        public PipeWriter Writer;
-
-        public WriterAdapter(PipeWriter writer)
-            => Writer = writer;
-
-        public void Advance(int count)
-            => Writer.Advance(count);
-
-        public Memory<byte> GetMemory(int sizeHint = 0)
-            => Writer.GetMemory(sizeHint);
-
-        public Span<byte> GetSpan(int sizeHint = 0)
-            => Writer.GetSpan(sizeHint);
-    }
-
-    private struct ParsingAdapter : IHttpRequestLineHandler, IHttpHeadersHandler
-    {
-        public BenchmarkApplication RequestHandler;
-
-        public ParsingAdapter(BenchmarkApplication requestHandler)
-            => RequestHandler = requestHandler;
-
-        public void OnStaticIndexedHeader(int index)
-            => RequestHandler.OnStaticIndexedHeader(index);
-
-        public void OnStaticIndexedHeader(int index, ReadOnlySpan<byte> value)
-            => RequestHandler.OnStaticIndexedHeader(index, value);
-
-        public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
-            => RequestHandler.OnHeader(name, value);
-
-        public void OnHeadersComplete(bool endStream)
-            => RequestHandler.OnHeadersComplete(endStream);
-
-        public void OnStartLine(HttpVersionAndMethod versionAndMethod, TargetOffsetPathLength targetPath, Span<byte> startLine)
-            => RequestHandler.OnStartLine(versionAndMethod, targetPath, startLine);
-    }
-}

+ 0 - 34
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Json.cs

@@ -1,34 +0,0 @@
-// 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.Buffers;
-using System.Text.Json;
-
-namespace PlatformBenchmarks;
-
-public partial class BenchmarkApplication
-{
-    private readonly static uint _jsonPayloadSize = (uint)JsonSerializer.SerializeToUtf8Bytes(new JsonMessage { message = "Hello, World!" }, SerializerContext.JsonMessage).Length;
-
-    private readonly static AsciiString _jsonPreamble =
-        _http11OK +
-        _headerServer + _crlf +
-        _headerContentTypeJson + _crlf +
-        _headerContentLength + _jsonPayloadSize.ToString();
-
-    private static void Json(ref BufferWriter<WriterAdapter> writer, IBufferWriter<byte> bodyWriter)
-    {
-        writer.Write(_jsonPreamble);
-
-        // Date header
-        writer.Write(DateHeader.HeaderBytes);
-
-        writer.Commit();
-
-        Utf8JsonWriter utf8JsonWriter = t_writer ??= new Utf8JsonWriter(bodyWriter, new JsonWriterOptions { SkipValidation = true });
-        utf8JsonWriter.Reset(bodyWriter);
-
-        // Body
-        JsonSerializer.Serialize(utf8JsonWriter, new JsonMessage { message = "Hello, World!" }, SerializerContext.JsonMessage);
-    }
-}

+ 0 - 46
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.MultipleQueries.cs

@@ -1,46 +0,0 @@
-// 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.
-
-#if DATABASE
-
-using System.IO.Pipelines;
-using System.Text.Json;
-using System.Text.Json.Serialization.Metadata;
-using System.Threading.Tasks;
-
-namespace PlatformBenchmarks
-{
-    public partial class BenchmarkApplication
-    {
-        private async Task MultipleQueries(PipeWriter pipeWriter, int count)
-        {
-            OutputMultipleQueries(pipeWriter, await Db.LoadMultipleQueriesRows(count), SerializerContext.WorldArray);
-        }
-
-        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
-
-            writer.Write(_dbPreamble);
-
-            var lengthWriter = writer;
-            writer.Write(_contentLengthGap);
-
-            // Date header
-            writer.Write(DateHeader.HeaderBytes);
-
-            writer.Commit();
-
-            Utf8JsonWriter utf8JsonWriter = t_writer ??= new Utf8JsonWriter(pipeWriter, new JsonWriterOptions { SkipValidation = true });
-            utf8JsonWriter.Reset(pipeWriter);
-
-            // Body
-            JsonSerializer.Serialize<TWorld[]>(utf8JsonWriter, rows, jsonTypeInfo);
-
-            // Content-Length
-            lengthWriter.WriteNumeric((uint)utf8JsonWriter.BytesCommitted);
-        }
-    }
-}
-
-#endif

+ 0 - 24
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs

@@ -1,24 +0,0 @@
-// 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.
-
-namespace PlatformBenchmarks;
-
-public partial class BenchmarkApplication
-{
-    private readonly static AsciiString _plaintextPreamble =
-        _http11OK +
-        _headerServer + _crlf +
-        _headerContentTypeText + _crlf +
-        _headerContentLength + _plainTextBody.Length.ToString();
-
-    private static void PlainText(ref BufferWriter<WriterAdapter> writer)
-    {
-        writer.Write(_plaintextPreamble);
-
-        // Date header
-        writer.Write(DateHeader.HeaderBytes);
-
-        // Body
-        writer.Write(_plainTextBody);
-    }
-}

+ 0 - 45
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.SingleQuery.cs

@@ -1,45 +0,0 @@
-// 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.
-
-#if DATABASE
-
-using System.IO.Pipelines;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace PlatformBenchmarks
-{
-    public partial class BenchmarkApplication
-    {
-        private async Task SingleQuery(PipeWriter pipeWriter)
-        {
-            OutputSingleQuery(pipeWriter, await Db.LoadSingleQueryRow());
-        }
-
-        private static void OutputSingleQuery(PipeWriter pipeWriter, World row)
-        {
-            var writer = GetWriter(pipeWriter, sizeHint: 180); // in reality it's 150
-
-            writer.Write(_dbPreamble);
-
-            var lengthWriter = writer;
-            writer.Write(_contentLengthGap);
-
-            // Date header
-            writer.Write(DateHeader.HeaderBytes);
-
-            writer.Commit();
-
-            Utf8JsonWriter utf8JsonWriter = t_writer ??= new Utf8JsonWriter(pipeWriter, new JsonWriterOptions { SkipValidation = true });
-            utf8JsonWriter.Reset(pipeWriter);
-
-            // Body
-            JsonSerializer.Serialize(utf8JsonWriter, row, SerializerContext.World);
-
-            // Content-Length
-            lengthWriter.WriteNumeric((uint)utf8JsonWriter.BytesCommitted);
-        }
-    }
-}
-
-#endif

+ 0 - 45
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.Updates.cs

@@ -1,45 +0,0 @@
-// 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.
-
-#if DATABASE
-
-using System.IO.Pipelines;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace PlatformBenchmarks
-{
-    public partial class BenchmarkApplication
-    {
-        private async Task Updates(PipeWriter pipeWriter, int count)
-        {
-            OutputUpdates(pipeWriter, await Db.LoadMultipleUpdatesRows(count));
-        }
-
-        private static void OutputUpdates(PipeWriter pipeWriter, World[] rows)
-        {
-            var writer = GetWriter(pipeWriter, sizeHint: 120 * rows.Length); // in reality it's 112 for one
-
-            writer.Write(_dbPreamble);
-
-            var lengthWriter = writer;
-            writer.Write(_contentLengthGap);
-
-            // Date header
-            writer.Write(DateHeader.HeaderBytes);
-
-            writer.Commit();
-
-            Utf8JsonWriter utf8JsonWriter = t_writer ??= new Utf8JsonWriter(pipeWriter, new JsonWriterOptions { SkipValidation = true });
-            utf8JsonWriter.Reset(pipeWriter);
-
-            // Body
-            JsonSerializer.Serialize( utf8JsonWriter, rows, SerializerContext.WorldArray);
-
-            // Content-Length
-            lengthWriter.WriteNumeric((uint)utf8JsonWriter.BytesCommitted);
-        }
-    }
-}
-
-#endif

+ 0 - 197
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkApplication.cs

@@ -1,197 +0,0 @@
-// 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.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;
-
-namespace PlatformBenchmarks;
-
-public partial class BenchmarkApplication
-{
-    private readonly static AsciiString _applicationName = "Kestrel Platform-Level Application";
-    public static AsciiString ApplicationName => _applicationName;
-
-    private readonly static AsciiString _crlf = "\r\n";
-    private readonly static AsciiString _eoh = "\r\n\r\n"; // End Of Headers
-    private readonly static AsciiString _http11OK = "HTTP/1.1 200 OK\r\n";
-    private readonly static AsciiString _http11NotFound = "HTTP/1.1 404 Not Found\r\n";
-    private readonly static AsciiString _headerServer = "Server: K";
-    private readonly static AsciiString _headerContentLength = "Content-Length: ";
-    private readonly static AsciiString _headerContentLengthZero = "Content-Length: 0";
-    private readonly static AsciiString _headerContentTypeText = "Content-Type: text/plain";
-    private readonly static AsciiString _headerContentTypeJson = "Content-Type: application/json";
-    private readonly static AsciiString _headerContentTypeHtml = "Content-Type: text/html; charset=UTF-8";
-
-    private readonly static AsciiString _dbPreamble =
-        _http11OK +
-        _headerServer + _crlf +
-        _headerContentTypeJson + _crlf +
-        _headerContentLength;
-
-    private readonly static AsciiString _plainTextBody = "Hello, World!";
-
-    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>";
-    private readonly static AsciiString _fortunesColumn = "</td><td>";
-    private readonly static AsciiString _fortunesRowEnd = "</td></tr>";
-    private readonly static AsciiString _fortunesTableEnd = "</table></body></html>";
-    private readonly static AsciiString _contentLengthGap = new string(' ', 4);
-
-#if DATABASE
-        public static RawDb Db { get; set; }
-#endif
-
-    [ThreadStatic]
-    private static Utf8JsonWriter t_writer;
-
-    public static class Paths
-    {
-        public readonly static AsciiString Json = "/json";
-        public readonly static AsciiString Plaintext = "/plaintext";
-        public readonly static AsciiString SingleQuery = "/db";
-        public readonly static AsciiString Fortunes = "/fortunes";
-        public readonly static AsciiString Updates = "/updates/";
-        public readonly static AsciiString MultipleQueries = "/queries/";
-        public readonly static AsciiString Caching = "/cached-worlds/";
-    }
-
-    private RequestType _requestType;
-    private int _queries;
-
-    public void OnStartLine(HttpVersionAndMethod versionAndMethod, TargetOffsetPathLength targetPath, Span<byte> startLine)
-    {
-        _requestType = versionAndMethod.Method == Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod.Get ? GetRequestType(startLine.Slice(targetPath.Offset, targetPath.Length), ref _queries) : RequestType.NotRecognized;
-    }
-
-    private RequestType GetRequestType(ReadOnlySpan<byte> path, ref int queries)
-    {
-#if !DATABASE
-        if (path.Length == 10 && path.SequenceEqual(Paths.Plaintext))
-        {
-            return RequestType.PlainText;
-        }
-        else if (path.Length == 5 && path.SequenceEqual(Paths.Json))
-        {
-            return RequestType.Json;
-        }
-#else
-            if (path.Length == 3 && path[0] == '/' && path[1] == 'd' && path[2] == 'b')
-            {
-                return RequestType.SingleQuery;
-            }
-            else if (path.Length == 9 && path[1] == 'f' && path.SequenceEqual(Paths.Fortunes))
-            {
-                return RequestType.Fortunes;
-            }
-            else if (path.Length >= 15 && path[1] == 'c' && path.StartsWith(Paths.Caching))
-            {
-                queries = ParseQueries(path.Slice(15));
-                return RequestType.Caching;
-            }
-            else if (path.Length >= 9 && path[1] == 'u' && path.StartsWith(Paths.Updates))
-            {
-                queries = ParseQueries(path.Slice(9));
-                return RequestType.Updates;
-            }
-            else if (path.Length >= 9 && path[1] == 'q' && path.StartsWith(Paths.MultipleQueries))
-            {
-                queries = ParseQueries(path.Slice(9));
-                return RequestType.MultipleQueries;
-            }
-#endif
-        return RequestType.NotRecognized;
-    }
-
-
-#if !DATABASE
-    private void ProcessRequest(ref BufferWriter<WriterAdapter> writer)
-    {
-        if (_requestType == RequestType.PlainText)
-        {
-            PlainText(ref writer);
-        }
-        else if (_requestType == RequestType.Json)
-        {
-            Json(ref writer, Writer);
-        }
-        else
-        {
-            Default(ref writer);
-        }
-    }
-#else
-
-        private static int ParseQueries(ReadOnlySpan<byte> parameter)
-        {
-            if (!Utf8Parser.TryParse(parameter, out int queries, out _) || queries < 1)
-            {
-                queries = 1;
-            }
-            else if (queries > 500)
-            {
-                queries = 500;
-            }
-
-            return queries;
-        }
-
-        private Task ProcessRequestAsync() => _requestType switch
-        {
-            RequestType.Fortunes => Fortunes(Writer),
-            RequestType.SingleQuery => SingleQuery(Writer),
-            RequestType.Caching => Caching(Writer, _queries),
-            RequestType.Updates => Updates(Writer, _queries),
-            RequestType.MultipleQueries => MultipleQueries(Writer, _queries),
-            _ => Default(Writer)
-        };
-
-        private static Task Default(PipeWriter pipeWriter)
-        {
-            var writer = GetWriter(pipeWriter, sizeHint: _defaultPreamble.Length + DateHeader.HeaderBytes.Length);
-            Default(ref writer);
-            writer.Commit();
-            return Task.CompletedTask;
-        }
-#endif
-    private readonly static AsciiString _defaultPreamble =
-        _http11NotFound +
-        _headerServer + _crlf +
-        _headerContentTypeText + _crlf +
-        _headerContentLengthZero;
-
-    private static void Default(ref BufferWriter<WriterAdapter> writer)
-    {
-        writer.Write(_defaultPreamble);
-
-        // Date header
-        writer.Write(DateHeader.HeaderBytes);
-    }
-
-    private enum RequestType
-    {
-        NotRecognized,
-        PlainText,
-        Json,
-        Fortunes,
-        SingleQuery,
-        Caching,
-        Updates,
-        MultipleQueries
-    }
-}

+ 0 - 58
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BenchmarkConfigurationHelpers.cs

@@ -1,58 +0,0 @@
-// 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.Net;
-using System.Runtime.InteropServices;
-
-namespace PlatformBenchmarks;
-
-public static class BenchmarkConfigurationHelpers
-{
-    public static IWebHostBuilder UseBenchmarksConfiguration(this IWebHostBuilder builder, IConfiguration configuration)
-    {
-        builder.UseConfiguration(configuration);
-
-        builder.UseSockets(options =>
-        {
-            if (int.TryParse(builder.GetSetting("threadCount"), out int threadCount))
-            {
-                options.IOQueueCount = threadCount;
-            }
-
-            options.WaitForDataBeforeAllocatingBuffer = false;
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
-            {
-                options.UnsafePreferInlineScheduling = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS") == "1";
-            }
-
-            Console.WriteLine($"Options: WaitForData={options.WaitForDataBeforeAllocatingBuffer}, PreferInlineScheduling={options.UnsafePreferInlineScheduling}, IOQueue={options.IOQueueCount}");
-        });
-
-        return builder;
-    }
-
-    public static IPEndPoint CreateIPEndPoint(this IConfiguration config)
-    {
-        var url = config["server.urls"] ?? config["urls"];
-
-        if (string.IsNullOrEmpty(url))
-        {
-            return new IPEndPoint(IPAddress.Loopback, 8080);
-        }
-
-        var address = BindingAddress.Parse(url);
-
-        IPAddress ip;
-
-        if (string.Equals(address.Host, "localhost", StringComparison.OrdinalIgnoreCase))
-        {
-            ip = IPAddress.Loopback;
-        }
-        else if (!IPAddress.TryParse(address.Host, out ip))
-        {
-            ip = IPAddress.IPv6Any;
-        }
-
-        return new IPEndPoint(ip, address.Port);
-    }
-}

+ 0 - 62
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BufferExtensions.cs

@@ -1,62 +0,0 @@
-// 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.Runtime.CompilerServices;
-using System.Text;
-
-namespace PlatformBenchmarks;
-
-// Same as KestrelHttpServer\src\Kestrel.Core\Internal\Http\PipelineExtensions.cs
-// However methods accept T : struct, IBufferWriter<byte> rather than PipeWriter.
-// This allows a struct wrapper to turn CountingBufferWriter into a non-shared generic,
-// while still offering the WriteNumeric extension.
-
-public static class BufferExtensions
-{
-    private const int _maxULongByteLength = 20;
-
-    [ThreadStatic]
-    private static byte[] _numericBytesScratch;
-
-    internal static void WriteUtf8String<T>(ref this BufferWriter<T> buffer, string text)
-         where T : struct, IBufferWriter<byte>
-    {
-        var byteCount = Encoding.UTF8.GetByteCount(text);
-        buffer.Ensure(byteCount);
-        byteCount = Encoding.UTF8.GetBytes(text.AsSpan(), buffer.Span);
-        buffer.Advance(byteCount);
-    }
-    [MethodImpl(MethodImplOptions.NoInlining)]
-    internal static void WriteNumericMultiWrite<T>(ref this BufferWriter<T> buffer, uint number)
-         where T : IBufferWriter<byte>
-    {
-        const byte AsciiDigitStart = (byte)'0';
-
-        var value = number;
-        var position = _maxULongByteLength;
-        var byteBuffer = NumericBytesScratch;
-        do
-        {
-            // Consider using Math.DivRem() if available
-            var quotient = value / 10;
-            byteBuffer[--position] = (byte)(AsciiDigitStart + (value - quotient * 10)); // 0x30 = '0'
-            value = quotient;
-        }
-        while (value != 0);
-
-        var length = _maxULongByteLength - position;
-        buffer.Write(new ReadOnlySpan<byte>(byteBuffer, position, length));
-    }
-
-    private static byte[] NumericBytesScratch => _numericBytesScratch ?? CreateNumericBytesScratch();
-
-    [MethodImpl(MethodImplOptions.NoInlining)]
-    private static byte[] CreateNumericBytesScratch()
-    {
-        var bytes = new byte[_maxULongByteLength];
-        _numericBytesScratch = bytes;
-        return bytes;
-    }
-}

+ 0 - 141
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/BufferWriter.cs

@@ -1,141 +0,0 @@
-// 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.Buffers;
-using System.Runtime.CompilerServices;
-
-namespace PlatformBenchmarks;
-
-public ref struct BufferWriter<T> where T : IBufferWriter<byte>
-{
-    private readonly T _output;
-    private Span<byte> _span;
-    private int _buffered;
-
-    public BufferWriter(T output, int sizeHint)
-    {
-        _buffered = 0;
-        _output = output;
-        _span = output.GetSpan(sizeHint);
-    }
-
-    public Span<byte> Span => _span;
-
-    public T Output => _output;
-
-    public int Buffered => _buffered;
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Commit()
-    {
-        var buffered = _buffered;
-        if (buffered > 0)
-        {
-            _buffered = 0;
-            _output.Advance(buffered);
-        }
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Advance(int count)
-    {
-        _buffered += count;
-        _span = _span.Slice(count);
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Write(ReadOnlySpan<byte> source)
-    {
-        if (_span.Length >= source.Length)
-        {
-            source.CopyTo(_span);
-            Advance(source.Length);
-        }
-        else
-        {
-            WriteMultiBuffer(source);
-        }
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Ensure(int count = 1)
-    {
-        if (_span.Length < count)
-        {
-            EnsureMore(count);
-        }
-    }
-
-    [MethodImpl(MethodImplOptions.NoInlining)]
-    private void EnsureMore(int count = 0)
-    {
-        if (_buffered > 0)
-        {
-            Commit();
-        }
-
-        _span = _output.GetSpan(count);
-    }
-
-    private void WriteMultiBuffer(ReadOnlySpan<byte> source)
-    {
-        while (source.Length > 0)
-        {
-            if (_span.Length == 0)
-            {
-                EnsureMore();
-            }
-
-            var writable = Math.Min(source.Length, _span.Length);
-            source[..writable].CopyTo(_span);
-            source = source[writable..];
-            Advance(writable);
-        }
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    internal void WriteNumeric(uint number)
-    {
-        const byte AsciiDigitStart = (byte)'0';
-
-        var span = this.Span;
-
-        // Fast path, try copying to the available memory directly
-        var advanceBy = 0;
-        if (span.Length >= 3)
-        {
-            if (number < 10)
-            {
-                span[0] = (byte)(number + AsciiDigitStart);
-                advanceBy = 1;
-            }
-            else if (number < 100)
-            {
-                var tens = (byte)((number * 205u) >> 11); // div10, valid to 1028
-
-                span[0] = (byte)(tens + AsciiDigitStart);
-                span[1] = (byte)(number - (tens * 10) + AsciiDigitStart);
-                advanceBy = 2;
-            }
-            else if (number < 1000)
-            {
-                var digit0 = (byte)((number * 41u) >> 12); // div100, valid to 1098
-                var digits01 = (byte)((number * 205u) >> 11); // div10, valid to 1028
-
-                span[0] = (byte)(digit0 + AsciiDigitStart);
-                span[1] = (byte)(digits01 - (digit0 * 10) + AsciiDigitStart);
-                span[2] = (byte)(number - (digits01 * 10) + AsciiDigitStart);
-                advanceBy = 3;
-            }
-        }
-
-        if (advanceBy > 0)
-        {
-            Advance(advanceBy);
-        }
-        else
-        {
-            BufferExtensions.WriteNumericMultiWrite(ref this, number);
-        }
-    }
-}

+ 0 - 11
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Configuration/AppSettings.cs

@@ -1,11 +0,0 @@
-// 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.
-
-namespace PlatformBenchmarks;
-
-public class AppSettings
-{
-    public string ConnectionString { get; set; }
-
-    public DatabaseServer Database { get; set; } = DatabaseServer.None;
-}

+ 0 - 12
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Configuration/DatabaseServer.cs

@@ -1,12 +0,0 @@
-// 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. 
-
-namespace PlatformBenchmarks;
-
-public enum DatabaseServer
-{
-    None,
-    SqlServer,
-    PostgreSql,
-    MySql
-}

+ 0 - 41
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/BatchUpdateString.cs

@@ -1,41 +0,0 @@
-// 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. 
-
-namespace PlatformBenchmarks;
-
-internal class BatchUpdateString
-{
-    private const int MaxBatch = 500;
-
-    public static DatabaseServer DatabaseServer;
-
-    internal static readonly string[] Ids = Enumerable.Range(0, MaxBatch).Select(i => $"@Id_{i}").ToArray();
-    internal static readonly string[] Randoms = Enumerable.Range(0, MaxBatch).Select(i => $"@Random_{i}").ToArray();
-
-    private static readonly string[] _queries = new string[MaxBatch + 1];
-
-    public static string Query(int batchSize)
-    {
-        if (_queries[batchSize] != null)
-        {
-            return _queries[batchSize];
-        }
-
-        var lastIndex = batchSize - 1;
-
-        var sb = StringBuilderCache.Acquire();
-
-        if (DatabaseServer == DatabaseServer.PostgreSql)
-        {
-            sb.Append("UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES ");
-            Enumerable.Range(0, lastIndex).ToList().ForEach(i => sb.Append($"(@Id_{i}, @Random_{i}), "));
-            sb.Append($"(@Id_{lastIndex}, @Random_{lastIndex}) ORDER BY 1) AS temp(id, randomNumber) WHERE temp.id = world.id");
-        }
-        else
-        {
-            Enumerable.Range(0, batchSize).ToList().ForEach(i => sb.Append($"UPDATE world SET randomnumber = @Random_{i} WHERE id = @Id_{i};"));
-        }
-
-        return _queries[batchSize] = StringBuilderCache.GetStringAndRelease(sb);
-    }
-}

+ 0 - 13
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/CachedWorld.cs

@@ -1,13 +0,0 @@
-// 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.
-
-namespace PlatformBenchmarks;
-
-public sealed class CachedWorld
-{
-    public int Id { get; set; }
-
-    public int RandomNumber { get; set; }
-
-    public static implicit operator CachedWorld(World world) => new CachedWorld { Id = world.Id, RandomNumber = world.RandomNumber };
-}

+ 0 - 22
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Fortune.cs

@@ -1,22 +0,0 @@
-// 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. 
-
-namespace PlatformBenchmarks;
-
-public readonly struct Fortune : IComparable<Fortune>, IComparable
-{
-    public Fortune(int id, string message)
-    {
-        Id = id;
-        Message = message;
-    }
-
-    public int Id { get; }
-
-    public string Message { get; }
-
-    public int CompareTo(object obj) => throw new InvalidOperationException("The non-generic CompareTo should not be used");
-
-    // Performance critical, using culture insensitive comparison
-    public int CompareTo(Fortune other) => string.CompareOrdinal(Message, other.Message);
-}

+ 0 - 9
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/JsonMessage.cs

@@ -1,9 +0,0 @@
-// 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.
-
-namespace PlatformBenchmarks;
-
-public struct JsonMessage
-{
-    public string message { get; set; }
-}

+ 0 - 272
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Providers/RawDbMySqlConnector.cs

@@ -1,272 +0,0 @@
-// 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.
-
-#if MYSQLCONNECTOR
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Caching.Memory;
-using MySqlConnector;
-
-namespace PlatformBenchmarks
-{
-    // Is semantically identical to RawDbNpgsql.cs.
-    // If you are changing RawDbMySqlConnector.cs, also consider changing RawDbNpgsql.cs.
-    public class RawDb
-    {
-        private readonly ConcurrentRandom _random;
-        private readonly string _connectionString;
-        private readonly MemoryCache _cache = new(
-            new MemoryCacheOptions
-            {
-                ExpirationScanFrequency = TimeSpan.FromMinutes(60)
-            });
-
-        public RawDb(ConcurrentRandom random, AppSettings appSettings)
-        {
-            _random = random;
-            _connectionString = appSettings.ConnectionString;
-        }
-
-        public async Task<World> LoadSingleQueryRow()
-        {
-            using (var db = new MySqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (cmd, _) = await CreateReadCommandAsync(db);
-                using (cmd)
-                {
-                    return await ReadSingleRow(cmd);
-                }
-            }
-        }
-
-        public async Task<World[]> LoadMultipleQueriesRows(int count)
-        {
-            var result = new World[count];
-
-            using (var db = new MySqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (cmd, idParameter) = await CreateReadCommandAsync(db);
-                using (cmd)
-                {
-                    for (int i = 0; i < result.Length; i++)
-                    {
-                        result[i] = await ReadSingleRow(cmd);
-                        idParameter.Value = _random.Next(1, 10001);
-                    }
-                }
-            }
-
-            return result;
-        }
-
-        public Task<CachedWorld[]> LoadCachedQueries(int count)
-        {
-            var result = new CachedWorld[count];
-            var cacheKeys = _cacheKeys;
-            var cache = _cache;
-            var random = _random;
-            for (var i = 0; i < result.Length; i++)
-            {
-                var id = random.Next(1, 10001);
-                var key = cacheKeys[id];
-                if (cache.TryGetValue(key, out object cached))
-                {
-                    result[i] = (CachedWorld)cached;
-                }
-                else
-                {
-                    return LoadUncachedQueries(id, i, count, this, result);
-                }
-            }
-
-            return Task.FromResult(result);
-
-            static async Task<CachedWorld[]> LoadUncachedQueries(int id, int i, int count, RawDb rawdb, CachedWorld[] result)
-            {
-                using (var db = new MySqlConnection(rawdb._connectionString))
-                {
-                    await db.OpenAsync();
-
-                    var (cmd, idParameter) = await rawdb.CreateReadCommandAsync(db);
-                    using (cmd)
-                    {
-                        Func<ICacheEntry, Task<CachedWorld>> create = async _ =>
-                        {
-                            return await rawdb.ReadSingleRow(cmd);
-                        };
-
-                        var cacheKeys = _cacheKeys;
-                        var key = cacheKeys[id];
-
-                        idParameter.Value = id;
-
-                        for (; i < result.Length; i++)
-                        {
-                            result[i] = await rawdb._cache.GetOrCreateAsync(key, create);
-
-                            id = rawdb._random.Next(1, 10001);
-                            idParameter.Value = id;
-                            key = cacheKeys[id];
-                        }
-                    }
-                }
-
-                return result;
-            }
-        }
-
-        public async Task PopulateCache()
-        {
-            using (var db = new MySqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (cmd, idParameter) = await CreateReadCommandAsync(db);
-                using (cmd)
-                {
-                    var cacheKeys = _cacheKeys;
-                    var cache = _cache;
-                    for (var i = 1; i < 10001; i++)
-                    {
-                        idParameter.Value = i;
-                        cache.Set<CachedWorld>(cacheKeys[i], await ReadSingleRow(cmd));
-                    }
-                }
-            }
-
-            Console.WriteLine("Caching Populated");
-        }
-
-        public async Task<World[]> LoadMultipleUpdatesRows(int count)
-        {
-            var results = new World[count];
-
-            using (var db = new MySqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (queryCmd, queryParameter) = await CreateReadCommandAsync(db);
-                using (queryCmd)
-                {
-                    for (int i = 0; i < results.Length; i++)
-                    {
-                        results[i] = await ReadSingleRow(queryCmd);
-                        queryParameter.Value = _random.Next(1, 10001);
-                    }
-                }
-
-                using (var updateCmd = new MySqlCommand(BatchUpdateString.Query(count), db))
-                {
-                    var ids = BatchUpdateString.Ids;
-                    var randoms = BatchUpdateString.Randoms;
-
-                    for (int i = 0; i < results.Length; i++)
-                    {
-                        var randomNumber = _random.Next(1, 10001);
-
-                        updateCmd.Parameters.Add(new MySqlParameter(ids[i], results[i].Id));
-                        updateCmd.Parameters.Add(new MySqlParameter(randoms[i], randomNumber));
-
-                        results[i].RandomNumber = randomNumber;
-                    }
-
-                    await updateCmd.ExecuteNonQueryAsync();
-                }
-            }
-
-            return results;
-        }
-
-        public async Task<List<Fortune>> LoadFortunesRows()
-        {
-            var result = new List<Fortune>();
-
-            using (var db = new MySqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                using (var cmd = new MySqlCommand("SELECT id, message FROM fortune", db))
-                {
-                    await cmd.PrepareAsync();
-                    
-                    using (var rdr = await cmd.ExecuteReaderAsync())
-                    {
-                        while (await rdr.ReadAsync())
-                        {
-                            result.Add(
-                                new Fortune
-                                (
-                                    id: rdr.GetInt32(0),
-                                    message: rdr.GetString(1)
-                                ));
-                        }
-                    }
-                }
-            }
-
-            result.Add(new Fortune(id: 0, message: "Additional fortune added at request time." ));
-            result.Sort();
-
-            return result;
-        }
-
-        private async Task<(MySqlCommand readCmd, MySqlParameter idParameter)> CreateReadCommandAsync(MySqlConnection connection)
-        {
-            var cmd = new MySqlCommand("SELECT id, randomnumber FROM world WHERE id = @Id", connection);
-            var parameter = new MySqlParameter("@Id", _random.Next(1, 10001));
-
-            cmd.Parameters.Add(parameter);
-
-            await cmd.PrepareAsync();
-            
-            return (cmd, parameter);
-        }
-        
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private async Task<World> ReadSingleRow(MySqlCommand cmd)
-        {
-            using (var rdr = await cmd.ExecuteReaderAsync(System.Data.CommandBehavior.SingleRow))
-            {
-                await rdr.ReadAsync();
-
-                return new World
-                {
-                    Id = rdr.GetInt32(0),
-                    RandomNumber = rdr.GetInt32(1)
-                };
-            }
-        }
-        
-        private static readonly object[] _cacheKeys = Enumerable.Range(0, 10001).Select(i => new CacheKey(i)).ToArray();
-
-        public sealed class CacheKey : IEquatable<CacheKey>
-        {
-            private readonly int _value;
-
-            public CacheKey(int value)
-                => _value = value;
-
-            public bool Equals(CacheKey key)
-                => key._value == _value;
-
-            public override bool Equals(object obj)
-                => ReferenceEquals(obj, this);
-
-            public override int GetHashCode()
-                => _value;
-
-            public override string ToString()
-                => _value.ToString();
-        }
-    }
-}
-
-#endif

+ 0 - 265
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Providers/RawDbNpgsql.cs

@@ -1,265 +0,0 @@
-// 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.
-
-#if NPGSQL
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Caching.Memory;
-using Npgsql;
-
-namespace PlatformBenchmarks
-{
-    // Is semantically identical to RawDbMySqlConnector.cs.
-    // If you are changing RawDbNpgsql.cs, also consider changing RawDbMySqlConnector.cs.
-    public class RawDb
-    {
-        private readonly ConcurrentRandom _random;
-        private readonly string _connectionString;
-        private readonly MemoryCache _cache = new(
-            new MemoryCacheOptions
-            {
-                ExpirationScanFrequency = TimeSpan.FromMinutes(60)
-            });
-
-        public RawDb(ConcurrentRandom random, AppSettings appSettings)
-        {
-            _random = random;
-            _connectionString = appSettings.ConnectionString;
-        }
-
-        public async Task<World> LoadSingleQueryRow()
-        {
-            using (var db = new NpgsqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (cmd, _) = CreateReadCommand(db);
-                using (cmd)
-                {
-                    return await ReadSingleRow(cmd);
-                }
-            }
-        }
-
-        public async Task<World[]> LoadMultipleQueriesRows(int count)
-        {
-            var result = new World[count];
-
-            using (var db = new NpgsqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (cmd, idParameter) = CreateReadCommand(db);
-                using (cmd)
-                {
-                    for (int i = 0; i < result.Length; i++)
-                    {
-                        result[i] = await ReadSingleRow(cmd);
-                        idParameter.TypedValue = _random.Next(1, 10001);
-                    }
-                }
-            }
-
-            return result;
-        }
-
-        public Task<CachedWorld[]> LoadCachedQueries(int count)
-        {
-            var result = new CachedWorld[count];
-            var cacheKeys = _cacheKeys;
-            var cache = _cache;
-            var random = _random;
-            for (var i = 0; i < result.Length; i++)
-            {
-                var id = random.Next(1, 10001);
-                var key = cacheKeys[id];
-                if (cache.TryGetValue(key, out object cached))
-                {
-                    result[i] = (CachedWorld)cached;
-                }
-                else
-                {
-                    return LoadUncachedQueries(id, i, count, this, result);
-                }
-            }
-
-            return Task.FromResult(result);
-
-            static async Task<CachedWorld[]> LoadUncachedQueries(int id, int i, int count, RawDb rawdb, CachedWorld[] result)
-            {
-                using (var db = new NpgsqlConnection(rawdb._connectionString))
-                {
-                    await db.OpenAsync();
-
-                    var (cmd, idParameter) = rawdb.CreateReadCommand(db);
-                    using (cmd)
-                    {
-                        Func<ICacheEntry, Task<CachedWorld>> create = async _ =>
-                        {
-                            return await rawdb.ReadSingleRow(cmd);
-                        };
-
-                        var cacheKeys = _cacheKeys;
-                        var key = cacheKeys[id];
-
-                        idParameter.TypedValue = id;
-
-                        for (; i < result.Length; i++)
-                        {
-                            result[i] = await rawdb._cache.GetOrCreateAsync(key, create);
-
-                            id = rawdb._random.Next(1, 10001);
-                            idParameter.TypedValue = id;
-                            key = cacheKeys[id];
-                        }
-                    }
-                }
-
-                return result;
-            }
-        }
-
-        public async Task PopulateCache()
-        {
-            using (var db = new NpgsqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (cmd, idParameter) = CreateReadCommand(db);
-                using (cmd)
-                {
-                    var cacheKeys = _cacheKeys;
-                    var cache = _cache;
-                    for (var i = 1; i < 10001; i++)
-                    {
-                        idParameter.TypedValue = i;
-                        cache.Set<CachedWorld>(cacheKeys[i], await ReadSingleRow(cmd));
-                    }
-                }
-            }
-
-            Console.WriteLine("Caching Populated");
-        }
-
-        public async Task<World[]> LoadMultipleUpdatesRows(int count)
-        {
-            var results = new World[count];
-
-            using (var db = new NpgsqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                var (queryCmd, queryParameter) = CreateReadCommand(db);
-                using (queryCmd)
-                {
-                    for (int i = 0; i < results.Length; i++)
-                    {
-                        results[i] = await ReadSingleRow(queryCmd);
-                        queryParameter.TypedValue = _random.Next(1, 10001);
-                    }
-                }
-
-                using (var updateCmd = new NpgsqlCommand(BatchUpdateString.Query(count), db))
-                {
-                    var ids = BatchUpdateString.Ids;
-                    var randoms = BatchUpdateString.Randoms;
-
-                    for (int i = 0; i < results.Length; i++)
-                    {
-                        var randomNumber = _random.Next(1, 10001);
-
-                        updateCmd.Parameters.Add(new NpgsqlParameter<int>(parameterName: ids[i], value: results[i].Id));
-                        updateCmd.Parameters.Add(new NpgsqlParameter<int>(parameterName: randoms[i], value: randomNumber));
-
-                        results[i].RandomNumber = randomNumber;
-                    }
-
-                    await updateCmd.ExecuteNonQueryAsync();
-                }
-            }
-
-            return results;
-        }
-
-        public async Task<List<Fortune>> LoadFortunesRows()
-        {
-            var result = new List<Fortune>(20);
-
-            using (var db = new NpgsqlConnection(_connectionString))
-            {
-                await db.OpenAsync();
-
-                using (var cmd = new NpgsqlCommand("SELECT id, message FROM fortune", db))
-                using (var rdr = await cmd.ExecuteReaderAsync())
-                {
-                    while (await rdr.ReadAsync())
-                    {
-                        result.Add(new Fortune
-                        (
-                            id:rdr.GetInt32(0),
-                            message: rdr.GetString(1)
-                        ));
-                    }
-                }
-            }
-
-            result.Add(new Fortune(id: 0, message: "Additional fortune added at request time." ));
-            result.Sort();
-
-            return result;
-        }
-
-        private (NpgsqlCommand readCmd, NpgsqlParameter<int> idParameter) CreateReadCommand(NpgsqlConnection connection)
-        {
-            var cmd = new NpgsqlCommand("SELECT id, randomnumber FROM world WHERE id = $1", connection);
-            var parameter = new NpgsqlParameter<int> { TypedValue = _random.Next(1, 10001) };
-
-            cmd.Parameters.Add(parameter);
-
-            return (cmd, parameter);
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private async Task<World> ReadSingleRow(NpgsqlCommand cmd)
-        {
-            using (var rdr = await cmd.ExecuteReaderAsync(System.Data.CommandBehavior.SingleRow))
-            {
-                await rdr.ReadAsync();
-
-                return new World
-                {
-                    Id = rdr.GetInt32(0),
-                    RandomNumber = rdr.GetInt32(1)
-                };
-            }
-        }
-
-        private static readonly object[] _cacheKeys = Enumerable.Range(0, 10001).Select(i => new CacheKey(i)).ToArray();
-
-        public sealed class CacheKey : IEquatable<CacheKey>
-        {
-            private readonly int _value;
-
-            public CacheKey(int value)
-                => _value = value;
-
-            public bool Equals(CacheKey key)
-                => key._value == _value;
-
-            public override bool Equals(object obj)
-                => ReferenceEquals(obj, this);
-
-            public override int GetHashCode()
-                => _value;
-
-            public override string ToString()
-                => _value.ToString();
-        }
-    }
-}
-
-#endif

+ 0 - 29
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/Random.cs

@@ -1,29 +0,0 @@
-// 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.CompilerServices;
-
-namespace PlatformBenchmarks;
-
-public class ConcurrentRandom
-{
-    private static int nextSeed = 0;
-
-    // Random isn't thread safe
-    [ThreadStatic]
-    private static Random _random;
-
-    private static Random Random => _random ?? CreateRandom();
-
-    [MethodImpl(MethodImplOptions.NoInlining)]
-    private static Random CreateRandom()
-    {
-        _random = new Random(Interlocked.Increment(ref nextSeed));
-        return _random;
-    }
-
-    public int Next(int minValue, int maxValue)
-    {
-        return Random.Next(minValue, maxValue);
-    }
-}

+ 0 - 14
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Data/World.cs

@@ -1,14 +0,0 @@
-// 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;
-
-[StructLayout(LayoutKind.Sequential, Size = 8)]
-public struct World
-{
-    public int Id { get; set; }
-
-    public int RandomNumber { get; set; }
-}

+ 0 - 65
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/DateHeader.cs

@@ -1,65 +0,0 @@
-// 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.Buffers.Text;
-using System.Diagnostics;
-using System.Text;
-
-namespace PlatformBenchmarks;
-
-/// <summary>
-/// Manages the generation of the date header value.
-/// </summary>
-internal static class DateHeader
-{
-    const int prefixLength = 8; // "\r\nDate: ".Length
-    const int dateTimeRLength = 29; // Wed, 14 Mar 2018 14:20:00 GMT
-    const int suffixLength = 2; // crlf
-    const int suffixIndex = dateTimeRLength + prefixLength;
-
-    private static readonly Timer s_timer = new((s) =>
-    {
-        SetDateValues(DateTimeOffset.UtcNow);
-    }, null, 1000, 1000);
-
-    private static byte[] s_headerBytesMaster = new byte[prefixLength + dateTimeRLength + 2 * suffixLength];
-    private static byte[] s_headerBytesScratch = new byte[prefixLength + dateTimeRLength + 2 * suffixLength];
-
-    static DateHeader()
-    {
-        var utf8 = Encoding.ASCII.GetBytes("\r\nDate: ").AsSpan();
-
-        utf8.CopyTo(s_headerBytesMaster);
-        utf8.CopyTo(s_headerBytesScratch);
-        s_headerBytesMaster[suffixIndex] = (byte)'\r';
-        s_headerBytesMaster[suffixIndex + 1] = (byte)'\n';
-        s_headerBytesMaster[suffixIndex + 2] = (byte)'\r';
-        s_headerBytesMaster[suffixIndex + 3] = (byte)'\n';
-        s_headerBytesScratch[suffixIndex] = (byte)'\r';
-        s_headerBytesScratch[suffixIndex + 1] = (byte)'\n';
-        s_headerBytesScratch[suffixIndex + 2] = (byte)'\r';
-        s_headerBytesScratch[suffixIndex + 3] = (byte)'\n';
-
-        SetDateValues(DateTimeOffset.UtcNow);
-        SyncDateTimer();
-    }
-
-    public static void SyncDateTimer() => s_timer.Change(1000, 1000);
-
-    public static ReadOnlySpan<byte> HeaderBytes => s_headerBytesMaster;
-
-    private static void SetDateValues(DateTimeOffset value)
-    {
-        lock (s_headerBytesScratch)
-        {
-            if (!Utf8Formatter.TryFormat(value, s_headerBytesScratch.AsSpan(prefixLength), out var written, 'R'))
-            {
-                throw new Exception("date time format failed");
-            }
-            Debug.Assert(written == dateTimeRLength);
-            var temp = s_headerBytesMaster;
-            s_headerBytesMaster = s_headerBytesScratch;
-            s_headerBytesScratch = temp;
-        }
-    }
-}

+ 0 - 28
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/HttpApplication.cs

@@ -1,28 +0,0 @@
-// 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.Threading.Tasks;
-using Microsoft.AspNetCore.Connections;
-
-namespace PlatformBenchmarks;
-
-public static class HttpApplicationConnectionBuilderExtensions
-{
-    public static IConnectionBuilder UseHttpApplication<TConnection>(this IConnectionBuilder builder) where TConnection : IHttpConnection, new()
-    {
-        return builder.Use(next => new HttpApplication<TConnection>().ExecuteAsync);
-    }
-}
-
-public class HttpApplication<TConnection> where TConnection : IHttpConnection, new()
-{
-    public Task ExecuteAsync(ConnectionContext connection)
-    {
-        var httpConnection = new TConnection
-        {
-            Reader = connection.Transport.Input,
-            Writer = connection.Transport.Output
-        };
-        return httpConnection.ExecuteAsync();
-    }
-}

+ 0 - 14
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/IHttpConnection.cs

@@ -1,14 +0,0 @@
-// 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.IO.Pipelines;
-using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
-
-namespace PlatformBenchmarks;
-
-public interface IHttpConnection : IHttpHeadersHandler, IHttpRequestLineHandler
-{
-    PipeReader Reader { get; set; }
-    PipeWriter Writer { get; set; }
-    Task ExecuteAsync();
-}

+ 0 - 8
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/NuGet.Config

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <packageSources>
-    <clear />
-    <add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" />
-    <add key="NuGet" value="https://api.nuget.org/v3/index.json" />
-  </packageSources>
-</configuration>

+ 0 - 40
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/PlatformBenchmarks.csproj

@@ -1,40 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
-  <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
-    <OutputType>Exe</OutputType>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-
-    <!-- Opt out of the "easy mode" of the CoreRT compiler (http://aka.ms/OptimizeCoreRT) -->
-    <TrimmerDefaultAction>link</TrimmerDefaultAction>
-    <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
-    <IlcPgoOptimize>true</IlcPgoOptimize>
-    <IlcTrimMetadata>true</IlcTrimMetadata>
-
-    <!-- This benchmark is marked Stripped, so we might as well do this: -->
-    <UseSystemResourceKeys>true</UseSystemResourceKeys>
-    <EventSourceSupport>false</EventSourceSupport>
-    <DebuggerSupport>false</DebuggerSupport>
-    <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
-    <ImplicitUsings>enable</ImplicitUsings>
-  </PropertyGroup>
-  
-  <PropertyGroup>
-    <DefineConstants Condition=" '$(DatabaseProvider)' != '' ">$(DefineConstants);DATABASE</DefineConstants>
-    <DefineConstants Condition=" '$(DatabaseProvider)' == 'Npgsql' ">$(DefineConstants);NPGSQL</DefineConstants>
-    <DefineConstants Condition=" '$(DatabaseProvider)' == 'MySqlConnector' ">$(DefineConstants);MYSQLCONNECTOR</DefineConstants>
-  </PropertyGroup>
-  
-  <ItemGroup>
-    <IlcArg Include="--instructionset:sse4.2" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <PackageReference Condition=" '$(DatabaseProvider)' == 'Npgsql' " Include="Npgsql" Version="6.0.0" />
-    <PackageReference Condition=" '$(DatabaseProvider)' == 'MySqlConnector' " Include="MySqlConnector" Version="2.0.0" />
-    <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
-  </ItemGroup>
-
-  <ItemGroup>
-      <None Include="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
-  </ItemGroup>
-</Project>

+ 0 - 90
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Program.cs

@@ -1,90 +0,0 @@
-// 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 Program
-{
-    public static string[] Args;
-
-    public static async Task Main(string[] args)
-    {
-        Args = args;
-
-        Console.WriteLine(BenchmarkApplication.ApplicationName);
-#if !DATABASE
-        Console.WriteLine(BenchmarkApplication.Paths.Plaintext);
-        Console.WriteLine(BenchmarkApplication.Paths.Json);
-#else
-            Console.WriteLine(BenchmarkApplication.Paths.Fortunes);
-            Console.WriteLine(BenchmarkApplication.Paths.SingleQuery);
-            Console.WriteLine(BenchmarkApplication.Paths.Updates);
-            Console.WriteLine(BenchmarkApplication.Paths.MultipleQueries);
-#endif
-        DateHeader.SyncDateTimer();
-
-        var host = BuildWebHost(args);
-        var config = (IConfiguration)host.Services.GetService(typeof(IConfiguration));
-        BatchUpdateString.DatabaseServer = config.Get<AppSettings>().Database;
-#if DATABASE
-            await BenchmarkApplication.Db.PopulateCache();
-#endif
-        await host.RunAsync();
-    }
-
-    public static IWebHost BuildWebHost(string[] args)
-    {
-        var config = new ConfigurationBuilder()
-            .AddJsonFile("appsettings.json")
-            .AddEnvironmentVariables()
-            .AddEnvironmentVariables(prefix: "ASPNETCORE_")
-            .AddCommandLine(args)
-            .Build();
-
-        var appSettings = config.Get<AppSettings>();
-#if DATABASE
-            Console.WriteLine($"Database: {appSettings.Database}");
-            Console.WriteLine($"ConnectionString: {appSettings.ConnectionString}");
-
-            if (appSettings.Database is DatabaseServer.PostgreSql
-                                     or DatabaseServer.MySql)
-            {
-                BenchmarkApplication.Db = new RawDb(new ConcurrentRandom(), appSettings);
-            }
-            else
-            {
-                throw new NotSupportedException($"{appSettings.Database} is not supported");
-            }
-#endif
-
-        var hostBuilder = new WebHostBuilder()
-            .UseBenchmarksConfiguration(config)
-            .UseKestrel((context, options) =>
-            {
-                var endPoint = context.Configuration.CreateIPEndPoint();
-
-                options.Listen(endPoint, builder =>
-                {
-                    builder.UseHttpApplication<BenchmarkApplication>();
-                });
-            })
-            .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;
-    }
-}

+ 0 - 11
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/Startup.cs

@@ -1,11 +0,0 @@
-// 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.
-
-namespace PlatformBenchmarks;
-
-public class Startup
-{
-    public void Configure(IApplicationBuilder app)
-    {
-    }
-}

+ 0 - 57
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/StringBuilderCache.cs

@@ -1,57 +0,0 @@
-// 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.Text;
-
-namespace PlatformBenchmarks;
-
-internal static class StringBuilderCache
-{
-    private const int DefaultCapacity = 1386;
-    private const int MaxBuilderSize = DefaultCapacity * 3;
-
-    [ThreadStatic]
-    private static StringBuilder t_cachedInstance;
-
-    /// <summary>Get a StringBuilder for the specified capacity.</summary>
-    /// <remarks>If a StringBuilder of an appropriate size is cached, it will be returned and the cache emptied.</remarks>
-    public static StringBuilder Acquire(int capacity = DefaultCapacity)
-    {
-        if (capacity <= MaxBuilderSize)
-        {
-            StringBuilder sb = t_cachedInstance;
-            if (capacity < DefaultCapacity)
-            {
-                capacity = DefaultCapacity;
-            }
-
-            if (sb != null)
-            {
-                // Avoid stringbuilder block fragmentation by getting a new StringBuilder
-                // when the requested size is larger than the current capacity
-                if (capacity <= sb.Capacity)
-                {
-                    t_cachedInstance = null;
-                    sb.Clear();
-                    return sb;
-                }
-            }
-        }
-        return new StringBuilder(capacity);
-    }
-
-    public static void Release(StringBuilder sb)
-    {
-        if (sb.Capacity <= MaxBuilderSize)
-        {
-            t_cachedInstance = sb;
-        }
-    }
-
-    public static string GetStringAndRelease(StringBuilder sb)
-    {
-        string result = sb.ToString();
-        Release(sb);
-        return result;
-    }
-}

+ 0 - 3
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.json

@@ -1,3 +0,0 @@
-{
-  "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnetcore-Benchmarks;Trusted_Connection=True;MultipleActiveResultSets=true"
-}

+ 0 - 4
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.mysql.json

@@ -1,4 +0,0 @@
-{
-  "ConnectionString": "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=1024;SslMode=None;ConnectionReset=false;ConnectionIdlePingTime=900;ConnectionIdleTimeout=0;AutoEnlist=false;DefaultCommandTimeout=0;ConnectionTimeout=0;IgnorePrepare=false;",
-  "Database": "mysql"
-}

+ 0 - 4
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.postgresql.json

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

+ 0 - 4
frameworks/CSharp/aspnetcore-corert/PlatformBenchmarks/appsettings.postgresql.updates.json

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

+ 0 - 28
frameworks/CSharp/aspnetcore-corert/README.md

@@ -1,28 +0,0 @@
-# ASP.NET Core Tests on Windows and Linux
-
-See [.NET CoreRT](https://github.com/dotnet/corert) and [ASP.NET Core](https://github.com/aspnet) for more information.
-
-This includes tests for plaintext and json serialization.
-
-## Infrastructure Software Versions
-
-**Language**
-
-* C# 7.0
-
-**Platforms**
-
-* .NET [CoreRT](https://github.com/dotnet/corert), a .NET Core runtime optimized for AOT (ahead of time compilation), with the accompanying .NET native compiler toolchain
-
-**Web Servers**
-
-* [Kestrel](https://github.com/aspnet/KestrelHttpServer)
-
-**Web Stack**
-
-* ASP.NET Core
-
-## Paths & Source for Tests
-
-* [Plaintext](PlatformBenchmarks/BenchmarkApplication.Plaintext.cs): "/plaintext"
-* [JSON Serialization](PlatformBenchmarks/BenchmarkApplication.Json.cs): "/json"

+ 0 - 16
frameworks/CSharp/aspnetcore-corert/aspcore-corert.dockerfile

@@ -1,16 +0,0 @@
-FROM mcr.microsoft.com/dotnet/sdk:6.0.100 AS build
-RUN apt-get update
-RUN apt-get -yqq install clang zlib1g-dev libkrb5-dev
-WORKDIR /app
-COPY PlatformBenchmarks .
-RUN dotnet publish -c Release -o out -r linux-x64
-
-FROM mcr.microsoft.com/dotnet/aspnet:6.0.0 AS runtime
-ENV ASPNETCORE_URLS http://+:8080
-ENV DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS 1
-WORKDIR /app
-COPY --from=build /app/out ./
-
-EXPOSE 8080
-
-ENTRYPOINT ["./PlatformBenchmarks"]

+ 0 - 63
frameworks/CSharp/aspnetcore-corert/benchmark_config.json

@@ -1,63 +0,0 @@
-{
-  "framework": "aspcore-corert",
-  "tests": [{
-    "default": {
-      "plaintext_url": "/plaintext",
-      "json_url": "/json",
-      "port": 8080,
-      "approach": "Stripped",
-      "classification": "Platform",
-      "database": "None",
-      "framework": "ASP.NET Core",
-      "language": "C#",
-      "orm": "Raw",
-      "platform": ".NET",
-      "flavor": "CoreRT",
-      "webserver": "Kestrel",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ASP.NET Core [Platform, CoreRT]",
-      "notes": "",
-      "versus": "aspcore"
-    },
-    "ado-pg": {
-      "fortune_url": "/fortunes",
-      "db_url": "/db",
-      "query_url": "/queries/",
-      "cached_query_url": "/cached-worlds/",
-      "port": 8080,
-      "approach": "Stripped",
-      "classification": "Platform",
-      "database": "Postgres",
-      "framework": "ASP.NET Core",
-      "language": "C#",
-      "orm": "Raw",
-      "platform": ".NET",
-      "flavor": "CoreRT",
-      "webserver": "Kestrel",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ASP.NET Core [Platform, CoreRT, Pg]",
-      "notes": "",
-      "versus": "aspcore-ado-pg"
-    },
-    "ado-pg-up": {
-      "update_url": "/updates/",
-      "port": 8080,
-      "approach": "Stripped",
-      "classification": "Platform",
-      "database": "Postgres",
-      "framework": "ASP.NET Core",
-      "language": "C#",
-      "orm": "Raw",
-      "platform": ".NET",
-      "flavor": "CoreRT",
-      "webserver": "Kestrel",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ASP.NET Core [Platform, CoreRT, Pg]",
-      "notes": "",
-      "versus": "aspcore-ado-pg-up"
-    }
-  }]
-}

+ 0 - 42
frameworks/CSharp/aspnetcore-corert/config.toml

@@ -1,42 +0,0 @@
-[framework]
-name = "aspnetcore-corert"
-
-[ado-pg]
-urls.db = "/db"
-urls.query = "/queries/"
-urls.fortune = "/fortunes"
-urls.cached_query = "/cached-worlds/"
-approach = "Stripped"
-classification = "Platform"
-database = "Postgres"
-database_os = "Linux"
-os = "Linux"
-orm = "Raw"
-platform = ".NET"
-webserver = "Kestrel"
-versus = "aspcore-ado-pg"
-
-[main]
-urls.plaintext = "/plaintext"
-urls.json = "/json"
-approach = "Stripped"
-classification = "Platform"
-database = "None"
-database_os = "Linux"
-os = "Linux"
-orm = "Raw"
-platform = ".NET"
-webserver = "Kestrel"
-versus = "aspcore"
-
-[ado-pg-up]
-urls.update = "/updates/"
-approach = "Stripped"
-classification = "Platform"
-database = "Postgres"
-database_os = "Linux"
-os = "Linux"
-orm = "Raw"
-platform = ".NET"
-webserver = "Kestrel"
-versus = "aspcore-ado-pg-up"

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

@@ -1,8 +1,9 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <OutputType>Exe</OutputType>
     <ImplicitUsings>enable</ImplicitUsings>
+    <TieredPGO>true</TieredPGO>
   </PropertyGroup>
 
   <ItemGroup>
@@ -13,10 +14,10 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
 
     <PackageReference Include="Dapper" Version="2.0.123" />
-    <PackageReference Include="MySqlConnector" Version="2.0.0" />
-    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.0" />
+    <PackageReference Include="MySqlConnector" Version="2.2.0" />
+    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.0" />
   </ItemGroup>
 </Project>

+ 0 - 57
frameworks/CSharp/aspnetcore/PlatformBenchmarks/AsciiString.cs

@@ -1,57 +0,0 @@
-// 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.Text;
-
-namespace PlatformBenchmarks;
-
-public readonly struct AsciiString : IEquatable<AsciiString>
-{
-    private readonly byte[] _data;
-
-    public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s);
-
-    private AsciiString(byte[] b) => _data = b;
-
-    public int Length => _data.Length;
-
-    public ReadOnlySpan<byte> AsSpan() => _data;
-
-    public static implicit operator ReadOnlySpan<byte>(AsciiString str) => str._data;
-    public static implicit operator byte[](AsciiString str) => str._data;
-
-    public static implicit operator AsciiString(string str) => new(str);
-
-    public override string ToString() => Encoding.ASCII.GetString(_data);
-    public static explicit operator string(AsciiString str) => str.ToString();
-
-    public bool Equals(AsciiString other) => ReferenceEquals(_data, other._data) || SequenceEqual(_data, other._data);
-    private bool SequenceEqual(byte[] data1, byte[] data2) => new Span<byte>(data1).SequenceEqual(data2);
-
-    public static bool operator ==(AsciiString a, AsciiString b) => a.Equals(b);
-    public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b);
-    public override bool Equals(object other) => (other is AsciiString @string) && Equals(@string);
-
-    public static AsciiString operator +(AsciiString a, AsciiString b)
-    {
-        var result = new byte[a.Length + b.Length];
-        a._data.CopyTo(result, 0);
-        b._data.CopyTo(result, a.Length);
-        return new AsciiString(result);
-    }
-
-    public override int GetHashCode()
-    {
-        // Copied from x64 version of string.GetLegacyNonRandomizedHashCode()
-        // https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/String.Comparison.cs
-        var data = _data;
-        int hash1 = 5381;
-        int hash2 = hash1;
-        foreach (int b in data)
-        {
-            hash1 = ((hash1 << 5) + hash1) ^ b;
-        }
-        return hash1 + (hash2 * 1566083941);
-    }
-
-}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio