Journal Le TapTempo du Web, mais minimaliste

Posté par  . Licence CC By‑SA.
8
15
juin
2022

Sommaire

Bonjour 'nal,

En ces temps de fortes chaleurs où les esprits s'échauffent et la bière se fait rare, une constante demeure : quand Java est là, C# n'est pas loin.

Le programme

7 lignes (écrit d'un seul trait, sans tester):

var app = WebApplication.CreateBuilder(args).Build();
app.MapGet("/", (HttpRequest request) =>
{
    request.Headers.Add("Location", $"https://avatar.spacefox.fr/Renard-{Random.Shared.Next(int.Parse(args.ElementAtOrDefault(1) ?? "0") + 1)}.png");
    return System.Net.HttpStatusCode.Redirect;
});
app.Run($"http://localhost:{args.FirstOrDefault() ?? "5001"}");

Fait grâce à ce tuto

dotnet new webapi -minimal

Le framework

ASP .NET 7 Preview 5, sorti hier. Avec comme toutes les versions, beaucoup d'améliorations de performances.

Le tuning

Pas possible, la CLI dotnet ne propose pas d'options permettant de modifier ces valeurs. :(

Et commeent on fait pour avoir une toute petite stack et heap, alors ?

Cela n'existe pas en dotnet, à moins d'aller créer son propre hôte pour le CLR. Autrement dit, c'est hard !

Une autre option serait docker (au moins pour limiter la taille mémoire à 16 Mo) mais je connais pas assez docker pour ce faire, et il se fait tard. :p

Et avec une compilation en natif ?

Oui, ça arrive timidement mais officiellement avec .NET 7.

Hélas, c'est encore une fois pas possible, car ça dépend du trimming et ASP .NET utilise encore pas mal d'API non-trimmables.

On se tape plein de warnings rien qu'avec le trimming:

dotnet publish -c Release --self-contained true -p:PublishTrimmed=true

Bon ben un ReadyToRun au moins ?

On peut au moins faire une première passe du JIT offline et ainsi réduire drastiqement le temps de démarrage :

dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=true

Et le setup avec NGINX et le serveur d'images môssieur ?

Ah ben moi je sais pas, j'ai juste le serveur libre Kestrel… ¯\(ツ)//¯

Et ceci, en appelant encore la CLI (dotnet run):

dotnet run -- 5001 1

Et la taille du package ?

En un seul fichier avec le runtime .NET intégré :

dotnet publish -c Release -r linux-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o bin/pub
-> % ls -l bin/pub
total 83808
-rw-r--r--. 1 max max      119 15 juin  20:37 appsettings.Development.json
-rw-r--r--. 1 max max      142 15 juin  20:37 appsettings.json
-rwxr-xr-x. 1 max max 85789791 15 juin  21:54 Fr.SpaceFox.Avatar
-rw-r--r--. 1 max max    19532 15 juin  21:54 Fr.SpaceFox.Avatar.pdb
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣴⣶⣿⠿⣿⣿⠿⠿⠿⠿⠿⢿⣿⣷⣶⣶⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣿⣿⣿⣿⣭⣤⣤⠤⠤⢤⣀⣀⣀⣀⣀⣀⣀⡈⠉⢙⣿⣿⣿⣶⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⠟⠋⠀⠀⣀⣤⣴⣿⡿⠿⢲⣤⣤⣄⣀⣀⠀⡀⠀⠀⣠⡾⠿⠟⠛⠛⠿⢿⣿⣿⣶⣤⣤⣀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣰⣾⠟⠁⢀⣤⣾⣿⠟⠋⣉⣀⣀⣀⣈⣉⣩⠭⠭⠭⠭⠭⠭⠭⠤⠤⠀⠀⠀⣠⣶⠿⠿⠿⠿⣿⣿⣿⣿⣶⠀⠀⠀⠀
⠀⠀⠀⠀⢠⣾⡟⠁⣠⣾⣿⡿⠋⠀⣠⡾⠛⠋⠉⠉⠙⠛⠿⣦⡀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠋⠀⠀⠀⣠⣾⣿⡟⢻⣿⠀⠀⠀⠀⠀
⠀⠀⠀⢠⣿⠏⠠⠞⠛⠛⠋⠀⢀⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠸⣷⠀⠀⠀⠀⠀⠀⠀⣾⠏⠀⠀⠀⠀⠀⠙⠻⠿⠁⢸⣿⠀⠀⠀⠀⠀
⠀⠀⠀⣾⡿⠀⠀⠀⠀⠀⠀⠀⣸⡏⠀⣀⣤⣤⡀⠀⠀⠀⠀⠀⣿⡄⠀⠀⠀⠀⠀⠠⣏⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⠀⠀⠀⠀⠀
⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⢰⣶⣿⡇⠀⣿⣿⣿⡿⠂⠀⠀⠀⠀⣿⠃⠀⠀⠀⠀⠀⠀⢿⣄⠀⠀⠀⠀⠀⠀⠀⣀⣼⠏⣿⡇⠀⠀⠀⠀
⠀⠀⢸⣿⠀⠀⠀⠀⠀⠚⠛⢛⣿⣿⣤⡙⠛⠋⠀⠀⠀⠀⢀⣼⠟⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠳⣶⣶⠿⠛⠛⠛⠿⣦⣿⣿⠀⠀⠀⠀
⠀⠀⣾⡇⠀⠀⠀⠀⠀⠀⠀⠞⠉⠀⠈⠛⠿⠶⣦⣤⣴⡾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⠟⠁⢀⣀⣤⣀⡀⠀⠙⢿⣧⠀⠀⠀
⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⢤⣤⣤⣤⣤⡤⠴⠖⢻⣿⠃⢀⣴⡿⠉⠉⠉⠻⣦⠀⠀⢿⣧⠀⠀
⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣤⣤⣤⣤⣤⣤⠤⠖⠀⣠⣿⠃⠀⣼⡿⣿⡟⢲⡶⣤⣿⣆⠀⢸⣿⠀⠀
⠀⠀⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠻⠿⢯⣥⣤⣤⣤⠖⠀⣿⡏⠀⢰⣿⣀⣿⣀⣸⣀⣿⣉⣿⠀⢸⣿⠀⠀
⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣤⣤⣤⣤⣤⣄⣀⣀⠀⣿⡇⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⣿⠂⣼⡇⠀⠀
⠀⠀⢸⣇⠀⢠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣧⠀⢸⡇⠀⠀⠀⠀⠀⠀⢰⡿⢠⣿⠁⠀⠀
⠀⠀⠘⣿⡀⠈⣧⠀⠸⡆⠀⢤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⢸⡇⠀⠀⠀⠀⠀⢠⣿⠁⣾⡇⠀⠀⠀
⠀⠀⠀⢸⣧⠀⠸⣧⠀⣷⠀⠀⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⢸⡇⠀⠀⠀⠀⠀⣾⡇⠀⣿⠀⠀⠀⠀
⠀⠀⠀⠀⢿⡄⠀⠘⣷⣻⡇⠀⠀⠙⢦⠀⠀⠀⠀⠀⠤⣤⣤⣤⣀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⣾⡇⠀⠀⠀⠀⠀⣿⡇⠀⣿⡇⠀⠀⠀
⠀⠀⠀⠀⠘⣿⡀⠀⠘⣿⣿⡀⠀⠀⠈⣷⠀⠀⠀⠀⠀⠐⠒⠾⠿⣷⣦⡀⠀⠀⠀⠀⣸⡏⢀⣿⠀⠀⠀⠀⠀⠀⢿⡇⠀⠸⣷⠀⠀⠀
⠀⠀⠀⠀⠀⠹⣧⠀⠀⢸⣿⣷⠀⠀⠀⢻⠀⠀⠀⠀⠀⠀⠐⠲⢶⣬⡙⠻⣦⠀⠀⢀⡿⠁⢸⡟⠉⠙⠓⠲⣄⠀⢸⣷⠀⠀⡇⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢹⣇⠀⠀⢻⡟⣧⠀⠀⠸⣄⠀⠀⠀⠀⢀⣀⣀⠀⠈⠻⢦⣄⠀⠀⣾⡇⠀⣿⡇⠀⠀⠀⠀⠈⢷⡀⣿⠀⠀⡇⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢿⣆⠀⠈⢷⡘⣧⠀⠀⠈⠳⣄⠀⠀⠀⠉⠉⠛⠲⣦⡀⠙⠷⠀⣿⠀⠀⣿⠶⠶⡶⠶⡶⢶⠶⢿⣿⠀⠀⡇⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⢿⣆⠀⠀⠻⣿⡷⣤⣀⠀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠙⠷⣄⠀⣿⠀⠀⢿⣧⣸⣧⣤⡇⢸⣆⣼⡏⠀⢀⡇⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣧⡀⠀⠈⠳⣄⠉⠓⢦⣀⠈⠻⢦⡀⠀⠀⠀⠀⠀⠈⢷⣿⠀⠀⠘⣿⣅⠀⠈⠉⢙⣻⡟⠀⠀⣼⡇⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣦⡀⠀⠈⠙⠶⣤⣽⣿⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⢿⣇⠀⠀⠈⠙⠻⠿⠿⠟⠋⠀⠀⣼⡿⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢷⣦⣀⠀⠀⠈⠙⠻⠿⢿⣿⣶⣶⡶⠶⠶⣤⣼⣿⣷⣄⣀⠀⠀⠀⠀⢀⣀⣤⡾⠋⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠿⣶⣤⣄⡀⠀⠀⠈⠉⠙⠛⠓⠶⠶⠶⠆⠀⠉⠛⠛⢻⣾⣿⡿⠟⠋⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⢿⣶⣦⣄⡀⠀⠀⠀⠀⠀⢀⣶⣶⣶⡶⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠻⢷⣶⣶⣶⣶⠾⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Tu veux pas voir la taille sans inclure le runtime ?

Non. Ça fera plusieurs Mio de toutes façons, autant y aller à fond les ballons. :p

Et puis maintenant que c'est multiplateforme, tout le monde n'a pas le runtime.
On est plus sous Windows, Dorothée !

Les performances

Sur un vieux laptop Fedora vieux de 10 ans et sur batterie.

On a peur de rien ici !

/home/max/dotnet/dotnet publish -r linux-x64 -p:PublishReadyToRun=true --self-contained true -c Release -o bin/publish
bin/publish/Fr.SpaceFox.Avatar 6666 21 &
ab -n 100000 -c 10 http://localhost:6666/

Ça tourne ! :

> % info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:6666
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/max/repos/Fr.SpaceFox.Avatar

Compte-rendu:

This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests


Server Software:        Kestrel
Server Hostname:        localhost
Server Port:            6666

Document Path:          /
Document Length:        3 bytes

Concurrency Level:      10
Time taken for tests:   11.375 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      14200000 bytes
HTML transferred:       300000 bytes
Requests per second:    8791.22 [#/sec] (mean)
Time per request:       1.137 [ms] (mean)
Time per request:       0.114 [ms] (mean, across all concurrent requests)
Transfer rate:          1219.10 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     0    1   0.4      1     119
Waiting:        0    1   0.4      1     117
Total:          1    1   0.4      1     119

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      1
 100%    119 (longest request)

8791.22.

Alors c'est ma machine, le manque de compilation AOT, ma connexion de campagne, ou le setup différent, voire le fait que je sois sur batterie le coupable, à votre avis ?

J'en sais rien, mais vu que j'ai pas de bogue je suis content de moi (pour une fois). :p

Allez, ciao !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.