Skip to content

Commit 13ff46a

Browse files
authored
Unhinged - Add high worker variant (#10280)
* Add high worker variant * bump unhinged to 9.0.7
1 parent a14b2c9 commit 13ff46a

File tree

5 files changed

+174
-0
lines changed

5 files changed

+174
-0
lines changed

frameworks/CSharp/wiredio/benchmark_config.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@
3737
"display_name": "Unhinged",
3838
"notes": "epoll"
3939
},
40+
"mcr-p": {
41+
"plaintext_url": "/plaintext",
42+
"json_url": "/json",
43+
"port": 8080,
44+
"approach": "Realistic",
45+
"classification": "Micro",
46+
"database": "None",
47+
"framework": "Unhinged",
48+
"language": "C#",
49+
"orm": "None",
50+
"platform": ".NET",
51+
"webserver": "Unhinged",
52+
"os": "Linux",
53+
"database_os": "Linux",
54+
"display_name": "Unhinged [p]",
55+
"notes": "epoll"
56+
},
4057
"gen": {
4158
"plaintext_url": "/plaintext",
4259
"json_url": "/json",

frameworks/CSharp/wiredio/config.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ platform = ".NET"
2525
webserver = "Unhinged"
2626
versus = "None"
2727

28+
[mcr-p]
29+
urls.plaintext = "/plaintext"
30+
urls.json = "/json"
31+
approach = "Realistic"
32+
classification = "Micro"
33+
os = "Linux"
34+
database_os = "Linux"
35+
orm = "None"
36+
platform = ".NET"
37+
webserver = "Unhinged"
38+
versus = "None"
39+
2840
[gen]
2941
urls.plaintext = "/plaintext"
3042
urls.json = "/json"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
9+
<IsTestAssetProject>true</IsTestAssetProject>
10+
<ServerGarbageCollection>true</ServerGarbageCollection>
11+
<TieredPGO>true</TieredPGO>
12+
13+
<!-- Required for self-contained publish -->
14+
<RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>
15+
<SelfContained>true</SelfContained>
16+
</PropertyGroup>
17+
18+
<ItemGroup Condition="$(PublishAot) == 'true'">
19+
<RuntimeHostConfigurationOption Include="System.Threading.ThreadPool.HillClimbing.Disable" Value="true" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Unhinged" Version="9.0.7" />
24+
</ItemGroup>
25+
</Project>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// ReSharper disable always SuggestVarOrType_BuiltInTypes
2+
// (var is avoided intentionally in this project so that concrete types are visible at call sites.)
3+
// ReSharper disable always StackAllocInsideLoop
4+
5+
using System.Runtime.CompilerServices;
6+
using System.Text.Json;
7+
using Unhinged;
8+
9+
#pragma warning disable CA2014
10+
11+
/* (MDA2AV)Dev notes:
12+
*
13+
* Wired.IO Platform benchmark using [Unhinged - https://github.com/MDA2AV/Unhinged] epoll engine.
14+
*
15+
* This test was created purely for benchmark/comparison between .NET solutions.
16+
* It should not be considered EVER as a go-to framework to build any kind of webserver!
17+
* For such purpose please use the main Wired.IO framework [Wired.IO - https://github.com/MDA2AV/Wired.IO].
18+
*
19+
* This benchmarks follows the JsonSerialization and PlainText rules imposed by the TechEmpower team.
20+
*
21+
* The Http parsing by the Unhinged engine is still naive(work in progress), yet it's development will not have any impact
22+
* on these benchmarks results as the extra request parsing overhead is much smaller than the read/send syscalls'.
23+
*/
24+
25+
namespace Platform;
26+
27+
[SkipLocalsInit]
28+
internal static class Program
29+
{
30+
public static void Main(string[] args)
31+
{
32+
var builder = UnhingedEngine
33+
.CreateBuilder()
34+
.SetPort(8080)
35+
36+
.SetNWorkersSolver(() => Environment.ProcessorCount )
37+
38+
// Accept up to 16384 connections
39+
.SetBacklog(16384)
40+
41+
// Max 512 epoll events per wake (quite overkill)
42+
.SetMaxEventsPerWake(512)
43+
44+
// Max 1024 connection per thread
45+
.SetMaxNumberConnectionsPerWorker(1024)
46+
47+
// 32KB in and 16KB out slabs to handle 16 pipeline depth
48+
.SetSlabSizes(32 * 1024, 16 * 1024)
49+
.InjectRequestHandler(RequestHandler);
50+
51+
var engine = builder.Build();
52+
engine.Run();
53+
}
54+
55+
private const string Json = "/json";
56+
private const string PlainText = "/plaintext";
57+
58+
private static ValueTask RequestHandler(Connection connection)
59+
{
60+
// FNV-1a Hashed routes to avoid string allocations
61+
if(connection.H1HeaderData.Route == Json) // /json
62+
CommitJsonResponse(connection);
63+
64+
else if (connection.H1HeaderData.Route == PlainText) // /plaintext
65+
CommitPlainTextResponse(connection);
66+
67+
return ValueTask.CompletedTask;
68+
}
69+
70+
[ThreadStatic] private static Utf8JsonWriter? t_utf8JsonWriter;
71+
private static readonly JsonContext SerializerContext = JsonContext.Default;
72+
private static void CommitJsonResponse(Connection connection)
73+
{
74+
connection.WriteBuffer.WriteUnmanaged("HTTP/1.1 200 OK\r\n"u8 +
75+
"Server: W\r\n"u8 +
76+
"Content-Type: application/json; charset=UTF-8\r\n"u8 +
77+
"Content-Length: 27\r\n"u8);
78+
connection.WriteBuffer.WriteUnmanaged(DateHelper.HeaderBytes);
79+
80+
t_utf8JsonWriter ??= new Utf8JsonWriter(connection.WriteBuffer, new JsonWriterOptions { SkipValidation = true });
81+
t_utf8JsonWriter.Reset(connection.WriteBuffer);
82+
83+
// Creating(Allocating) a new JsonMessage every request
84+
var message = new JsonMessage { Message = "Hello, World!" };
85+
// Serializing it every request
86+
JsonSerializer.Serialize(t_utf8JsonWriter, message, SerializerContext.JsonMessage);
87+
}
88+
89+
private static void CommitPlainTextResponse(Connection connection)
90+
{
91+
connection.WriteBuffer.WriteUnmanaged("HTTP/1.1 200 OK\r\n"u8 +
92+
"Server: W\r\n"u8 +
93+
"Content-Type: text/plain\r\n"u8 +
94+
"Content-Length: 13\r\n"u8);
95+
connection.WriteBuffer.WriteUnmanaged(DateHelper.HeaderBytes);
96+
connection.WriteBuffer.WriteUnmanaged("Hello, World!"u8);
97+
}
98+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Build
2+
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
3+
RUN apk add --no-cache clang build-base zlib-dev linux-headers
4+
WORKDIR /src
5+
COPY src/PlatformP/ ./PlatformP/
6+
WORKDIR /src/PlatformP
7+
RUN dotnet publish -c Release \
8+
-r linux-musl-x64 \
9+
--self-contained true \
10+
-p:PublishAot=true \
11+
-p:OptimizationPreference=Speed \
12+
-p:GarbageCollectionAdaptationMode=0 \
13+
-o /app/out
14+
15+
# Runtime (musl)
16+
FROM mcr.microsoft.com/dotnet/runtime-deps:9.0-alpine
17+
ENV URLS=http://+:8080
18+
WORKDIR /app
19+
COPY --from=build /app/out ./
20+
RUN chmod +x ./Platform
21+
EXPOSE 8080
22+
ENTRYPOINT ["./Platform"]

0 commit comments

Comments
 (0)