Dit is de diepe duik in lange vorm. Voor een snellere, vlot leesbare versie, zie de begeleidende blogpost.

1. Inleiding: gewoontestapels versus echte werklasten
Technologiekeuzes in volwassen organisaties mislukken zelden omdat niemand een benchmarkblogpost leest. Ze falen omdat de proces de keuze is zwak: de voorkeur van een luide senior engineer, een wervingspijplijn vol met één taal, of een enkele indrukwekkende demo op een conferentie. Ondertussen combineert het product latentiegevoelige API's, batchafstemming, edge-authenticatie in NGINX, interne CLI's en af en toe een serverloze piek. Eén runtime kan niet optimaal zijn voor al deze vormen.
Dit artikel legt het uit Polyglot-benchmarks - een live vergelijkingsdashboard en de open workflow-voorbeelden/benchmarks harnas erachter - als een beslissingskader, geen fanboy-klassement. Het doel is bewijs dat u aan een architectuurbeslissingsrecord (ADR) kunt koppelen: dezelfde eindpunten, dezelfde laadgenerator, dezelfde containerindeling, meerdere talen.
Ik zal geen doorvoercijfers in proza verzinnen. Wanneer u het harnas uitvoert, toont het dashboard de gemeten vereisten en latentiepercentielen voor die hardware en Docker-installatie. Beschouw elke statische rangschikking hier als kwalitatieve patronen die zijn afgestemd op de testfamilies van het harnas en de ingebouwde oordeelskopie van het dashboard.
2. Wat zijn Polyglot-benchmarks?
Polyglot-benchmarks wordt gehost bij polyglot-benchmarks.fictionally.org (Fictieve merkinfrastructuur in het ecosysteem met workflowvoorbeelden). De landingskop vergelijkt:
- NGINX njs - JavaScript-modules in voorraad NGINX
- Open Resty Lua — Lua aan de rand van OpenResty
- Python FastAPI — Uvicorn ASGI-app
- Ga naar net/http — standaard bibliotheekserver
- Roest Actix-web — asynchroon HTTP op Actix
- Broodje — JavaScript-runtime met native HTTP-server
- Java (Javalin / Jetty) — lichtgewicht JVM HTTP op Jetty
- Kotlin (Ktor / Netty) - coroutine-vriendelijke JVM HTTP op Netty
De live kop is een 8-taal vergelijking: njs versus Lua versus Python versus Go versus Rust versus Bun versus Java versus Kotlin. De ondertitel kadert de bedoeling: optreden voor lange polling/chat/wachtrij/API-workloads - verbindingszware, JSON-zware en routing-zware paden in plaats van een enkele "hallo wereld" wagenrace. JVM-winkels krijgen eindelijk dezelfde beursoppervlakte als Go/Rust/Bun in plaats van een aparte “enterprise” anekdote.
2.1 Wat het dashboard laat zien
Terwijl een run vordert, peilt de gebruikersinterface /data/results.json elke twee seconden en geeft het volgende weer:
- Verzoeken/sec (doorvoer) - geaggregeerd van
wrkper taal per toets - Gemiddelde latentie En P99-staartlatentie – in milliseconden volgens het latentiemodel van wrk
- TTFB (tijd tot eerste byte) - van curl-timing JSON naast wrk
- Overzichtstabel — winnaars per test met ★ markers op de beste cellen
- Gedetailleerde testkaarten — staafdiagrammen en metrische tabellen (P50, P90, P99.9, fouten)
- Latentie percentielverdeling - gemiddeld over tests
- Oordeel — het beste voor uw gebruiksscenario – verhaal zodra status is
complete
Die structuur is bewust ARB-vriendelijk: grafieken voor dia's, tabellen voor spreadsheets, verhalend voor het risicogedeelte van een ADR.
3. Het harnas van de workflow-voorbeelden
Alles wat reproduceerbaar is, leeft onder benchmarks/ in de workflow-voorbeelden opslagplaats. Indeling op het hoogste niveau:
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 Docker Compose-topologie
docker-compose.yml definieert geïsoleerde services op een gedeeld netwerk:
nginx-njs— poort 8081, configuraties van./njsopenresty-lua— poort 8082python-fastapi— poort 8084, opgebouwd uit./pythongo-server— poort 8085rust-actix— poort 8086bun-server— poort 8087java-server— poort 8088, Javalin / Jetty van./javakotlin-server— poort 8089, Ktor / Netty van./kotlindashboard— poort 8083, bedient HTML en koppelt deresultsvolume bij/databench— Alpine-container die wordt geïnstalleerdcurl,wrk,jq, wacht op afhankelijkheden, wordt uitgevoerdbench.sh
De bankloper deelt de results volume met het dashboard, zodat de resultaten live verschijnen zonder handmatige kopie.
3.2 bench.sh-methodologie
De shell-driver codeert expliciet de eerlijkheidsregels:
- Duur:
10sper eindpunt per taal - Onderwerpen: 4
- Aansluitingen: 100 gelijktijdig
- Opwarming: 50 ronden slaan
/helloop elke server vóór getimede tests - Per server: curl timing JSON (dns, connect, ttfb, totaal) plus wrk met
wrk_json.lua
In het script zijn zeven tests door pijpen gescheiden:
| Identiteitskaart | Naam | Intentie | Eindpunt |
|---|---|---|---|
| 1 | Platte tekst | Basislijn: minimale respons, raamwerkoverhead | /hello |
| 2 | JSON-serialisatie | Bouw en serialiseer een JSON-array met 100 items | /json |
| 3 | CPU-gebonden (fib 30) | Recursieve fibonacci(30) — pure CPU | /cpu?n=30 |
| 4 | String-manipulatie | Bouw, splits, hoofdletters, voeg 1000 segmenten samen | /string |
| 5 | Inspectie aanvragen | Headers, methode, argumenten → JSON | /request_info?foo=bar&baz=123 |
| 6 | Subaanvraag + Transformeren | Interne subaanvraag, JSON parseren, transformeren | /subrequest |
| 7 | Routeringslogica | Voorwaardelijke routering op queryparameters | /route?action=greet&name=bench |
Elke taal implementeert hetzelfde routeoppervlak (zie golang/main.go, python/main.py, java/, kotlin/, NGINX-configuraties, enz.) zodat de verschillen de runtime en het framework weerspiegelen, en niet de niet-overeenkomende specificaties.
4. Waarom “polyglot” ertoe doet (zonder fanatisme)
Meertalige architectuur betekent niet dat iedere ingenieur acht talen leert. Het betekent begrensde contexten zorg voor een runtime die past:
- Rand vlak - auth, snelheidslimieten, routing: Lua of njs binnen NGINX die u al gebruikt
- Kern API-vlak — bedrijfslogica met SLO's: Go of Rust
- JVM-vlak — bestaande Spring/Jakarta landgoederen, gedeelde bibliotheken, huurdiepte: Java (Javalin) of Kotlin (Ktor)
- Gegevensvlak — ETL, notebooks, ML-lijm: Python
- Realtime JS-vlak — WebSockets, gedeelde typen met frontend: Bun of Node waar snelheid wint
Uniforme stapels optimaliseren HR en inkoop. Polyglot-benchmarks optimaliseren geschikt per werklast met meetbare trade-offs op tafel.
5. Afmetingen die ertoe doen
Raw req/s is de statistiek die het snelst op Slack reist. Het is ook het gemakkelijkst om verkeerd te lezen. Gebruik een rubriek met meerdere kolommen:
| Criterium | Domineert wanneer... | Hars signaal |
|---|---|---|
| p50 / p99-latentie | Gebruikersgerichte API's, chat, lange poll | wrk latentie percentielen; dashboard P99-diagram |
| Doorvoer (RPS) | Gateways met hoge fan-out, batchaggregators | werk RPS; samenvattende winnaarkolom |
| Geheugen per verbinding | Duizenden inactieve WebSockets | Kwalitatieve + productieprofilering (niet volledig op orde) |
| TTFB | CDN-misser, koude paden, mobiele netwerken | krul time_starttransfer in resultaten-JSON |
| LOC / complexiteit | Startups, gereguleerde veranderingsbeheersing | Vergelijk implementaties in verschillende mappen |
| Bouw- en CI-tijd | Frequente implementaties, veel services | Docker bouwt profielen per taal |
| Ops last | Klein platformteam | Bestaande NGINX-vaardigheden → Lua/njs; anders containers |
| Hostingkosten | Always-on versus schaal-naar-nul | Afgeleid van geheugen + CPU onder belasting (productie) |
6. Beslissingsmatrix
Het onderstaande diagram is de kwalitatieve kaart die we gebruiken in beoordelingen – illustratieve leiders, geen vervanging voor het gebruik van het harnas op uw uitrusting.

Lees het eerst in de rij: kies de vorm van uw werklast en vervolgens de gewichtskolommen. Als twee criteria conflicteren (bijvoorbeeld de beste RPS versus de laagste LOC), is die spanning de ADR-discussie die de moeite waard is.
7. Patronen van dozen (voorbeeld etikettering)
De volgende kaarten maken gebruik van testfamilies voor architecturale keuzes. Leiders op uw machine verschijnen na een run op het dashboard. Beschouw dit gedeelte niet als vaste scores.
7.1 API latentiegevoelig (tests 1–2, 5–7)
JSON API's en routerintensieve handlers weerspiegelen Tests 2, 5 en 7. Gecompileerde asynchrone runtimes (Rust Actix, Go) leiden doorgaans tot doorvoer en staartlatentie in deze klasse van synthetische HTTP-benchmarks; Bun zit vaak dichtbij JSON-zware paden met JS-ergonomie. Java (Javalin) En Kotlin (Ktor) geef JVM-teams een eerlijke beoordeling ten opzichte van de leiders op dezelfde routes – handig als de vraag is “blijf op de JVM met een lichtere stapel” versus “herschrijven in Go/Rust.” Python FastAPI ruilt ruwe RPS in voor ontwikkelingssnelheid – het dashboardoordeel noemt dit expliciet.
7.2 CPU-gebonden microwerk (Test 3)
Fibonacci(30) isoleert CPU zonder I/O. Verwacht Rust and Go om te schitteren; geïnterpreteerde stapels betalen overhead; JVM JIT kan er na het opwarmen sterker uitzien dan een koud 10s-venster impliceert - verleng de duur als dat je echte profiel is. Als uw echte service I/O-gebonden is, moet u deze rij niet te zwaar wegen; het is een stresstest voor rekenintensieve middleware, en niet de typische CRUD.
7.3 Randtransformatie (tests 6–7, NGINX-varianten)
Subaanvraag- en routeringstests zijn waar Open Resty Lua En NGINX njs behoren: nul extra hop, gedeeld werkgeheugen, operationele teams beheren NGINX al. Het oordeel van het harnas beveelt Go/Rust aan voor de kernchat/wachtrij-backends en Lua/njs aan de rand – een verstandige splitsing die veel bedrijven al informeel runnen.
7.4 Batch-ETL en datapijplijn
Het HTTP-harnas emuleert geen Spark- of magazijnbelastingen. Voor batch geven teams meestal prioriteit aan het Python-ecosysteem en de orkestratie (Airflow, Dagster) of Go-werknemers voor doorvoer. Gebruik Polyglot Benchmarks voor de API-oppervlakken en besturingsvlakken die taken worden blootgelegd, niet voor de batch-engine zelf.
7.5 Snel intern gereedschap
API's voor interne beheerders met een lage QPS en een hoog wijzigingspercentage: Python of Bun/Node winnen vaak op het gebied van snelheid en werving. Voer Test 2 (JSON) en Test 5 (inspectie) uit om er zeker van te zijn dat de overhead acceptabel is; als p99 onder de 100 verbindingen piekt, heroverweeg dan voordat u promoveert naar klantgerichte niveaus.
7.6 JVM-domein (Java & Kotlin)
Veel bedrijven gebruiken al Java of Kotlin voor gedeelde bibliotheken, compliance-tools en rekruteringsdiepte. Het harnas java-server (Javalin op Jetty, poort 8088) en kotlin-server (Ktor op Netty, poort 8089) implementeren dezelfde zeven eindpunten als Go en Rust, zodat u kunt kwantificeren of een lichtere JVM HTTP-stack “goed genoeg” is voor een bepaalde SLO voordat u deze herschrijft. Geef de voorkeur aan Kotlin wanneer gelijktijdigheid in coroutine-stijl en Kotlin-eerste teams ertoe doen; geven de voorkeur aan Java wanneer de omliggende landgoed- en bibliotheekgrafiek al Java-gericht is. Gebruik de live dashboardrijen. Ga er niet van uit dat Spring Boot-nummers gelijk zijn aan Javalin/Ktor-nummers.
8. Werkstroomdiagram

De reproduceerbare lus: specificeer de werklast → voer het Compose-harnas uit → publiceer resultaten naar het Fictionally-dashboard (of uw interne kloon) → neem een ADR op met configuratie-metagegevens → voer opnieuw uit wanneer runtimes of hardware veranderen.
9. Hoe u uw eigen vergelijking kunt uitvoeren
- Kloon:
git clone https://github.com/bwalia/workflow-examples.git && cd workflow-examples/benchmarks - Beginstapel:
docker compose up --build— bouwt alle taalafbeeldingen, start het dashboard op poort 8083, voert de bench automatisch uit. - Horloge: open
http://localhost:8083(of de openbare site wanneer een gehoste run actief is). - Verlengen: voeg een map toe
myruntime/, spiegel eindpuntpaden, registreer een service indocker-compose.yml, voeg de server toe aanSERVERSinbench.sh. - Lading aanpassen: bewerking
DURATION,THREADS,CONNECTIONSbovenaanbench.sh— documenteer wijzigingen in uw ADR. - Voeg productievormige tests toe: bijv. auth middleware, ORM-query, 50 KB payload – behoud de pariteit tussen talen.
Voor CI voert u Compose uit in een nachtelijke workflow, archiveren results.json als een artefact en faalt alleen op de regressiedrempels die u definieert (bijvoorbeeld p99 +20% week na week in test 2).
10. Antipatronen
- Alleen de winnaar van Test 1 kiezen — platte tekst is voorstander van minimale stapels; het negeert JSON, CPU en routeringspijn.
- Het negeren van teamvaardigheden — Roest in de productie zonder mentoren is duur in incidenttijd.
- Hostkosten negeren — 2× RPS is nutteloos als het geheugen per pod uw factuur verdubbelt.
- Eén taal voor de hele organisatie verplicht stellen – vernietigt legitieme edge versus core-splitsingen.
- Vervanging van productieprofilering — synthetische HTTP ≠ uw ORM, cache of regionale latentie.
- Vergelijken in tegenstelling tot hardware — laptop Docker ≠ blank metaal ≠ K8s-limieten; noteer de klasse in het ADR.
11. Voordelen voor technisch leiderschap
- ARB-pakketten — dashboardscreenshots exporteren +
results.json+ Stel hasj samen. - Leveranciersneutraal bewijs – geen verkoopdeck van een enkele cloud- of framework-leverancier.
- Duidelijkheid bij het instappen - nieuwe medewerkers zien *waarom* service A Go is en service B Python.
- Risicoreductie - stuur de nummer twee in een schaduwdienst voordat je hem herschrijft.
- FinOps-gesprekken — koppel staartlatentie aan automatisch schalen en geheugenruimte.
- Platform-routekaart – rechtvaardig de investering in NGINX-vaardigheden versus een andere K8s-microservice.
12. Beperkingen
- Synthetische werklasten — zeven HTTP-tests kunnen geen Kafka-consumenten, GPU-taken of complexe ORM-grafieken vertegenwoordigen.
- Docker-netwerken — voegt overhead toe; absolute aantallen verschillen van blank metaal.
- Enkele machineklasse — gehoste resultaten weerspiegelen welke hardware Fictionally ook gebruikt; uw cijfers zullen verschillen.
- Geen persistentielaag — database- en cache-effecten zijn door het ontwerp afwezig.
- Korte looptijd — 10 seconden per test mogen geen GC-pauzes of opwarmkliffen blootleggen; verlengen voor stresscampagnes.
Behoud continue profilering (eBPF, APM, belastingtests tegen staging) als de bron van waarheid voor productie. Polyglot Benchmarks verkleinen de taal en raamwerk debat met reproduceerbare basislijnen.
13. Conclusie
De standaardstack-bias is comfortabel; het is ook de manier waarop teams de verkeerde runtime voor de taak verzenden. Polyglot-benchmarks en de workflow-voorbeelden harnas beurt “welke taal wint?” in “welke taal wint voor deze werklastrij?” – met grafieken die uw ARB kan citeren.
Splits de repository, voeg de eindpunten toe die op uw hot paths lijken, voer Compose uit en koppel de resultaten aan de volgende architectuurbeslissing. De metgezel blogpost is de vijf minuten durende versie om te delen; dit artikel is de referentie.
Gepubliceerd door Workstation (werkstation.co.uk). Benchmarkdashboard gehost op polyglot-benchmarks.fictionally.org in het ecosysteem Fictieve voorbeelden.
SEO-momentopname voor dit artikel
- SEO-titel: Polyglot-benchmarks: het juiste hulpmiddel voor de taak
- Metabeschrijving: Vergelijk njs, Lua, Python, Go, Rust, Bun, Java en Kotlin op dezelfde HTTP-workloads. Reproduceerbaar harnas, live dashboard, beslissingsmatrix voor architecten.
- Primaire trefwoorden: meertalige benchmarks, taalvergelijking, architectuurbeslissingen, workflowvoorbeelden, prestatiebenchmark, Rust vs Go, Java vs Kotlin, FastAPI, Javalin, Ktor
- Twitter / X (minder dan 280 tekens): Polyglot Benchmarks: dezelfde 7 HTTP-tests voor njs, Lua, Python, Go, Rust, Bun, Java, Kotlin - live dashboard + workflow-voorbeelden. Geen enkele winnaar; een beslissingskader. #Rust #GoLang #Java #Kotlin #Bunjs #polyglot
- LinkedIn-bericht: We hebben een diepgaande duik gepubliceerd over Polyglot Benchmarks – hoe u kunt stoppen met het uit gewoonte kiezen van één stapel voor de hele organisatie en kunt beginnen met het afstemmen van runtimes op workloads. Acht talen (waaronder Java/Javalin en Kotlin/Ktor), zeven vergelijkbare tests, Docker Compose + wrk, live resultaten op polyglot-benchmarks.fictionally.org, bron op github.com/bwalia/workflow-examples/tree/main/benchmarks. Inclusief beslissingsmatrix, antipatronen en ADR-richtlijnen. Van Workstation-engineering. #Rust #GoLang #Java #Kotlin #Bunjs #Lua #Python #njs #FastAPI #Javalin #Ktor #OpenResty #polyglot #benchmarks