Il s’agit de la plongée profonde en version longue. Pour une version plus rapide et lisible, consultez le article de blog compagnon.

1. Introduction : piles d'habitudes par rapport aux charges de travail réelles
Les choix technologiques dans les organisations matures échouent rarement parce que personne ne lit un article de blog de référence. Ils échouent parce que processus car le choix est faible : la préférence d'un ingénieur senior bruyant, un pipeline de recrutement rempli d'une seule langue ou une seule démonstration impressionnante lors d'une conférence. Pendant ce temps, le produit mélange des API sensibles à la latence, une réconciliation par lots, une authentification périphérique dans NGINX, des CLI internes et des pics occasionnels sans serveur. Un environnement d'exécution ne peut pas être optimal pour toutes ces formes.
Cet article explique Benchmarks polyglottes — un tableau de bord de comparaison en direct et l'open exemples/benchmarks de workflow harnais derrière lui - comme un cadre de décision, pas un classement des fanboys. L'objectif est d'obtenir des preuves que vous pouvez joindre à un enregistrement de décision d'architecture (ADR) : mêmes points de terminaison, même générateur de charge, même disposition de conteneur, plusieurs langues.
Je n'inventerai pas de chiffres de débit en prose. Lorsque vous exécutez le harnais, le tableau de bord affiche les demandes mesurées et les centiles de latence pour ce matériel et la configuration Docker. Traitez ici tout classement statique comme des modèles qualitatifs alignés sur les familles de tests du harnais et la copie de verdict intégrée au tableau de bord.
2. Qu'est-ce que Polyglot Benchmarks ?
Benchmarks polyglottes est hébergé chez polyglot-benchmarks.fictionally.org (Infrastructure de marque fictive dans l'écosystème d'exemples de flux de travail). Le titre de l'atterrissage compare :
- NGINX njs — Modules JavaScript en stock NGINX
- OuvrirResty Lua — Lua au bord sur OpenResty
- Python FastAPI — Application Uvicorn ASGI
- Allez sur Internet/http — serveur de bibliothèque standard
- Rust Actix-web — HTTP asynchrone sur Actix
- Chignon — Runtime JavaScript avec serveur HTTP natif
- Java (Javalin/Jetty) — HTTP JVM léger sur Jetty
- Kotlin (Ktor / Netty) - JVM HTTP compatible avec les coroutines sur Netty
Le titre en direct est un 8 langues comparaison: njs contre Lua contre Python contre Go contre Rust contre Bun contre Java contre Kotlin. Le sous-titre encadre l'intention : performance pour longues interrogations / chat / file d'attente / charges de travail API - des chemins gourmands en connexions, en JSON et en routage plutôt qu'une seule course de chars « hello world ». Les magasins JVM obtiennent enfin la même surface équitable que Go/Rust/Bun au lieu d'une anecdote « d'entreprise » distincte.
2.1 Ce que montre le tableau de bord
Pendant qu'une exécution progresse, l'interface utilisateur interroge /data/results.json toutes les deux secondes et affiche :
- Requêtes/s (débit) — agrégé à partir de
wrkpar langue et par test - Latence moyenne et Latence de queue P99 — en millisecondes à partir du modèle de latence de wrk
- TTFB (temps jusqu'au premier octet) - de curl timing JSON aux côtés de wrk
- Tableau récapitulatif — gagnants par test avec des marqueurs ★ sur les meilleures cellules
- Cartes de test détaillées — graphiques à barres et tableaux métriques (P50, P90, P99.9, erreurs)
- Distribution centile de latence - en moyenne sur les tests
- Verdict : le meilleur pour votre cas d'utilisation — récit une fois le statut obtenu
complete
Cette structure est délibérément adaptée à l'ARB : graphiques pour les diapositives, tableaux pour les feuilles de calcul, récit pour la section sur les risques d'un ADR.
3. L'exploitation des exemples de workflow
Tout ce qui est reproductible vit sous benchmarks/ dans le exemples de workflow dépôt. Disposition de niveau supérieur :
benchmarks/
bench.sh # orchestrates tests, writes results.json
wrk_json.lua # wrk done() → JSON summary (RPS, percentiles)
docker-compose.yml # eight app services + dashboard + bench runner
njs/ # NGINX + njs module
lua/ # OpenResty nginx.conf
python/ # FastAPI + Dockerfile
golang/ # net/http main.go
rust/ # Actix-web + Cargo
bun/ # Bun server.ts
java/ # Javalin on Jetty
kotlin/ # Ktor on Netty
dashboard/ # static index.html + nginx.conf
3.1 Topologie Docker Compose
docker-compose.yml définit des services isolés sur un réseau partagé :
nginx-njs— port 8081, configurations de./njsopenresty-lua-port 8082python-fastapi— port 8084, construit à partir de./pythongo-server-port 8085rust-actix-port 8086bun-server-port 8087java-server— port 8088, Javalin / Jetty de./javakotlin-server— port 8089, Ktor / Netty de./kotlindashboard— le port 8083, sert HTML et monte leresultsvolume à/databench— Conteneur alpin qui installecurl,wrk,jq, attend les dépendances, exécutebench.sh
Le coureur de banc partage le results volume avec le tableau de bord afin que les résultats apparaissent en direct sans copie manuelle.
3.2 Méthodologie bench.sh
Le pilote shell code explicitement les règles d’équité :
- Durée:
10spar point de terminaison et par langue - Sujets : 4
- Relations: 100 simultanés
- Réchauffer: 50 coups réussis
/hellosur chaque serveur avant les tests chronométrés - Par serveur : curl timing JSON (dns, connect, ttfb, total) plus travailler avec
wrk_json.lua
Sept tests sont délimités par des barres verticales dans le script :
| IDENTIFIANT | Nom | Intention | Point de terminaison |
|---|---|---|---|
| 1 | Texte brut | Base de référence – réponse minimale, surcharge du framework | /hello |
| 2 | Sérialisation JSON | Créer et sérialiser un tableau JSON de 100 éléments | /json |
| 3 | Lié à CPU (fib 30) | Fibonacci récursif (30) – CPU pur | /cpu?n=30 |
| 4 | Manipulation des chaînes | Construire, diviser, majuscules, rejoindre 1000 segments | /string |
| 5 | Demander une inspection | En-têtes, méthode, arguments → JSON | /request_info?foo=bar&baz=123 |
| 6 | Sous-requête + Transformation | Sous-requête interne, analyser JSON, transformer | /subrequest |
| 7 | Logique de routage | Routage conditionnel sur les paramètres de requête | /route?action=greet&name=bench |
Chaque langage implémente la même surface de routage (voir golang/main.go, python/main.py, java/, kotlin/, configurations NGINX, etc.) afin que les différences reflètent le temps d'exécution et le framework, et non des spécifications incompatibles.
4. Pourquoi « polyglotte » est important (sans fanatisme)
L'architecture polyglotte ne signifie pas que chaque ingénieur apprend huit langues. Cela signifie contextes délimités obtenez un runtime qui correspond :
- Plan de bord — authentification, limites de débit, routage : Lua ou njs dans NGINX que vous exploitez déjà
- Avion de base API — logique métier avec SLO : Go ou Rust
- Plan JVM — domaines Spring/Jakarta existants, bibliothèques partagées, profondeur de recrutement : Java (Javalin) ou Kotlin (Ktor)
- Plan de données — ETL, notebooks, colle ML : Python
- Avion JS en temps réel — WebSockets, types partagés avec frontend : Bun ou Node où la vélocité gagne
Des piles uniformes optimisent les RH et les achats. Les benchmarks polyglottes optimisent ajustement par charge de travail avec des compromis mesurables sur la table.
5. Des dimensions qui comptent
Les requêtes brutes sont la métrique qui circule le plus rapidement sur Slack. C’est aussi le plus facile à mal lire. Utilisez une rubrique à plusieurs colonnes :
| Critère | Domine quand… | Signal de faisceau |
|---|---|---|
| latence p50 / p99 | API destinés aux utilisateurs, chat, long sondage | percentiles de latence de travail ; tableau de bord tableau P99 |
| Débit (RPS) | Passerelles à diffusion élevée, agrégateurs par lots | travailler RPS ; colonne récapitulative des gagnants |
| Mémoire par connexion | Des milliers de WebSockets inactifs | Profilage qualitatif + production (pas entièrement exploité) |
| TTFB | CDN manqué, chemins froids, réseaux mobiles | boucle time_starttransfer dans les résultats JSON |
| LOC / complexité | Startups, contrôle du changement régulé | Comparez les implémentations dans les dossiers |
| Temps de construction et de CI | Déploiements fréquents, nombreux services | Docker crée des profils par langue |
| Charge opérationnelle | Petite équipe de plateforme | Compétences NGINX existantes → Lua/njs ; sinon des conteneurs |
| Coût d'hébergement | Toujours actif ou évolutif | Dérivé de la mémoire + CPU sous charge (production) |
6. Matrice de décision
Le diagramme ci-dessous est la carte qualitative que nous utilisons dans les critiques – des leaders illustratifs, et non un substitut à l’utilisation du harnais sur votre kit.

Lisez-le par ligne en premier : choisissez la forme de votre charge de travail, puis pondérez les colonnes. Si deux critères entrent en conflit (par exemple, le meilleur RPS par rapport au LOC le plus bas), cette tension vaut la peine d'être discutée en ADR.
7. Modèles de cas (exemple d'étiquetage)
Les cartes suivantes associent les familles de tests aux choix architecturaux. Les leaders de votre machine apparaissent sur le tableau de bord après une exécution – ne traitez pas cette section comme des scores fixes.
7.1 API sensible à la latence (Tests 1–2, 5–7)
Les API JSON et les gestionnaires de routage lourds reflètent les tests 2, 5 et 7. Les environnements d'exécution asynchrones compilés (Rust Actix, Go) sont généralement en tête en termes de débit et de latence finale dans cette classe de tests HTTP synthétiques ; Bun se trouve souvent à proximité des chemins lourds en JSON avec l'ergonomie JS. Java (Javalin) et Kotlin (Ktor) donnez aux équipes JVM une lecture équitable par rapport aux leaders sur les mêmes routes – utile lorsque la question est « rester sur la JVM avec une pile plus légère » plutôt que « réécrire dans Go/Rust ». Python FastAPI échange le RPS brut contre la vitesse de développement – le verdict du tableau de bord le souligne explicitement.
7.2 Micro-travail lié à CPU (Test 3)
Fibonacci(30) isole CPU sans E/S. Attendez-vous à ce que Rust and Go brille ; les piles interprétées paient des frais généraux ; JVM JIT peut paraître plus fort après l'échauffement qu'une fenêtre froide de 10 secondes ne le laisse entendre - prolongez la durée si tel est votre profil réel. Si votre service réel est lié aux E/S, ne surpondérez pas cette ligne : il s'agit d'un test de résistance pour les middlewares gourmands en calcul, et non d'un CRUD typique.
7.3 Transformation Edge (Tests 6 à 7, variantes NGINX)
Les tests de sous-requête et de routage sont l'endroit où OuvrirResty Lua et NGINX njs appartiennent : zéro saut supplémentaire, mémoire de travail partagée, les équipes opérationnelles gèrent déjà NGINX. Le verdict du harnais recommande Go/Rust pour les principaux backends de discussion/file d’attente et Lua/njs en périphérie – une répartition judicieuse que de nombreuses entreprises gèrent déjà de manière informelle.
7.4 ETL par lots et pipeline de données
Le harnais HTTP n'émule pas les charges Spark ou d'entrepôt. Pour le traitement par lots, les équipes donnent généralement la priorité à l'écosystème et à l'orchestration Python (Airflow, Dagster) ou aux travailleurs Go pour le débit. Utilisez des références polyglottes pour le Surfaces et plans de contrôle API ces travaux exposent, pas pour le moteur batch lui-même.
7.5 Outil interne rapide
API d'administrateur interne avec un faible QPS et un taux de modification élevé : Python ou Bun/Node gagnent souvent en termes de rapidité et d'embauche. Exécutez le test 2 (JSON) et le test 5 (inspection) pour vous assurer que la surcharge est acceptable ; si p99 atteint moins de 100 connexions, reconsidérez-le avant de passer aux niveaux destinés aux clients.
7.6 Domaine JVM (Java et Kotlin)
De nombreuses entreprises utilisent déjà Java ou Kotlin pour les bibliothèques partagées, les outils de conformité et la profondeur du recrutement. Le harnais java-server (Javalin sur Jetty, port 8088) et kotlin-server (Ktor sur Netty, port 8089) implémente les mêmes sept points de terminaison que Go et Rust, afin que vous puissiez quantifier si une pile HTTP JVM plus légère est « assez bonne » pour un SLO donné avant une réécriture. Préférez Kotlin lorsque la concurrence de type coroutine et les premières équipes Kotlin sont importantes ; préférez Java lorsque le domaine environnant et le graphique de la bibliothèque sont déjà centrés sur Java. Utilisez les lignes du tableau de bord en direct – ne supposez pas que les nombres Spring Boot sont égaux aux nombres Javalin/Ktor.
8. Diagramme de flux de travail

La boucle reproductible : spécifier la charge de travail → exécuter le harnais Compose → publier les résultats sur le tableau de bord Fictionally (ou votre clone interne) → enregistrer un ADR avec les métadonnées de configuration → réexécuter lorsque les environnements d'exécution ou le matériel changent.
9. Comment exécuter votre propre comparaison
- Cloner:
git clone https://github.com/bwalia/workflow-examples.git && cd workflow-examples/benchmarks - Démarrer la pile :
docker compose up --build- crée toutes les images de langue, démarre le tableau de bord sur le port 8083, exécute automatiquement le banc. - Montre: ouvrir
http://localhost:8083(ou le site public lorsqu'une exécution hébergée est active). - Étendre: ajouter un dossier
myruntime/, mettre en miroir les chemins des points de terminaison, enregistrer un service dansdocker-compose.yml, ajoutez le serveur àSERVERSdansbench.sh. - Personnaliser la charge : modifier
DURATION,THREADS,CONNECTIONSau sommet debench.sh— documenter les modifications dans votre ADR. - Ajoutez des tests en forme de production : par ex. middleware d'authentification, requête ORM, charge utile de 50 Ko - gardez la parité entre les langues.
Pour CI, exécutez Compose dans un flux de travail nocturne, archivez results.json en tant qu'artefact, et échoue uniquement sur les seuils de régression que vous définissez (par exemple p99 + 20 % semaine après semaine sur le test 2).
10. Anti-modèles
- Choisir le gagnant du test 1 uniquement — le texte brut favorise les piles minimales ; il ignore JSON, CPU et les problèmes de routage.
- Ignorer les compétences de l'équipe — La rouille en production sans mentors coûte cher en temps d'incident.
- Ignorer les coûts d'hébergement — 2× RPS est inutile si la mémoire par pod double votre facture.
- Rendre obligatoire une seule langue à l’échelle de l’organisation - détruit les divisions légitimes Edge vs Core.
- Remplacement du profilage de production — HTTP synthétique ≠ votre ORM, cache ou latence régionale.
- Comparer le matériel contrairement — Docker pour ordinateur portable ≠ bare metal ≠ limites K8s ; notez la classe dans l’ADR.
11. Avantages pour le leadership en ingénierie
- Packs ARB — exporter les captures d'écran du tableau de bord +
results.json+ Composez du hachage. - Preuve indépendante du fournisseur - pas de présentation de vente d'un seul fournisseur de cloud ou de framework.
- Clarté d'intégration — les nouvelles recrues voient *pourquoi* le service A est Go et le service B est Python.
- Réduction des risques - pilotez le finaliste dans un service fantôme avant les réécritures.
- Conversations FinOps - reliez la latence de queue à la mise à l'échelle automatique et à la marge de mémoire.
- Feuille de route de la plateforme - justifiez l'investissement en compétences NGINX par rapport à un autre microservice K8.
12. Limites
- Charges de travail synthétiques — sept tests HTTP ne peuvent pas représenter les consommateurs Kafka, les tâches GPU ou les graphiques ORM complexes.
- Mise en réseau Docker — ajoute des frais généraux ; les nombres absolus diffèrent du métal nu.
- Classe de machine unique — les résultats hébergés reflètent le matériel utilisé de manière fictive ; vos chiffres seront différents.
- Pas de couche de persistance — les effets de base de données et de cache sont absents de par leur conception.
- Durée de courte durée — 10 s par test ne doivent pas exposer les pauses du GC ou les falaises d'échauffement ; prolonger les campagnes de lutte contre le stress.
Conservez le profilage continu (eBPF, APM, tests de charge par rapport au staging) comme source de vérité pour la production. Polyglot Benchmarks réduit le langage et cadre débat avec des lignes de base reproductibles.
13. Conclusion
Le biais de pile par défaut est confortable ; c'est également ainsi que les équipes fournissent le mauvais moteur d'exécution pour le travail. Benchmarks polyglottes et le exemples de workflow exploitez le tour « quelle langue gagne ? » dans "quelle langue gagne pour cette ligne de charge de travail?" - avec des graphiques que votre ARB peut citer.
Forkez le dépôt, ajoutez les points de terminaison qui ressemblent à vos hot paths, exécutez Compose et joignez les résultats à la prochaine décision d'architecture. Le compagnon article de blog est la version de cinq minutes à partager ; cet article est la référence.
Publié par Workstation (poste de travail.co.uk). Tableau de bord de référence hébergé sur polyglot-benchmarks.fictionally.org dans l’écosystème Exemples fictifs.
Aperçu SEO pour cet article
- Titre SEO : Benchmarks polyglottes : le bon outil pour le travail
- Méta description : Comparez njs, Lua, Python, Go, Rust, Bun, Java et Kotlin sur les mêmes charges de travail HTTP. Harnais reproductible, tableau de bord live, matrice de décision pour les architectes.
- Mots-clés principaux : benchmarks polyglottes, comparaison de langages, décisions d'architecture, exemples de workflow, benchmark de performances, Rust vs Go, Java vs Kotlin, FastAPI, Javalin, Ktor
- Twitter / X (moins de 280 caractères) : Benchmarks polyglottes : mêmes 7 tests HTTP sur njs, Lua, Python, Go, Rust, Bun, Java, Kotlin — tableau de bord en direct + faisceau d'exemples de workflow. Pas un seul gagnant ; un cadre de décision. #Rust #GoLang #Java #Kotlin #Bunjs #polyglotte
- Publication LinkedIn : Nous avons publié une étude approfondie sur Polyglot Benchmarks : comment arrêter de choisir une seule pile à l'échelle de l'organisation par habitude et commencer à faire correspondre les temps d'exécution aux charges de travail. Huit langages (dont Java/Javalin et Kotlin/Ktor), sept tests comparables, Docker Compose + wrk, résultats en direct sur polyglot-benchmarks.fictionally.org, source sur github.com/bwalia/workflow-examples/tree/main/benchmarks. Comprend une matrice de décision, des anti-modèles et des conseils ADR. De l'ingénierie Workstation. #Rust #GoLang #Java #Kotlin #Bunjs #Lua #Python #njs #FastAPI #Javalin #Ktor #OpenResty #polyglot #benchmarks