Este é o mergulho profundo de formato longo. Para uma versão mais rápida e legível, consulte o postagem complementar no blog.

1. Introdução: pilhas de hábitos versus cargas de trabalho reais
As escolhas tecnológicas em organizações maduras raramente falham porque ninguém leu uma postagem de blog de referência. Eles falham porque o processo a escolha é fraca: a preferência de um engenheiro sênior, um pipeline de contratação cheio de um idioma ou uma única demonstração impressionante em uma conferência. Enquanto isso, o produto combina APIs sensíveis à latência, reconciliação em lote, autenticação de borda em NGINX, CLIs internos e picos ocasionais sem servidor. Um tempo de execução não pode ser ideal para todas essas formas.
Este artigo explica Benchmarks poliglotas — um painel de comparação ao vivo e o aberto exemplos/benchmarks de fluxo de trabalho arnês atrás dele - como um quadro de decisão, não uma tabela de classificação de fanboy. O objetivo é uma evidência que você pode anexar a um registro de decisão de arquitetura (ADR): mesmos endpoints, mesmo gerador de carga, mesmo layout de contêiner, vários idiomas.
Não vou inventar números de rendimento em prosa. Quando você executa o chicote, o painel mostra solicitações medidas e percentis de latência para esse hardware e configuração do Docker. Trate qualquer classificação estática aqui como padrões qualitativos alinhados com as famílias de testes do equipamento e a cópia do veredicto integrada do painel.
2. O que são benchmarks poliglotas?
Benchmarks poliglotas está hospedado em polyglot-benchmarks.fictionally.org (Infraestrutura de marca fictícia no ecossistema de exemplos de fluxo de trabalho). O título de destino compara:
- NGINX njs — Módulos JavaScript dentro do estoque NGINX
- OpenResty Lua — Lua no limite do OpenResty
- Python FastAPI - Aplicativo Uvicorn ASGI
- Acesse a rede/http — servidor de biblioteca padrão
- Rust Actix-web — HTTP assíncrono no Actix
- Pão — Tempo de execução JavaScript com servidor HTTP nativo
- Java (Javalin/Jetty) — JVM HTTP leve em Jetty
- Kotlin (Ktor/Netty) — JVM HTTP compatível com corrotinas em Netty
O título ao vivo é um 8 idiomas comparação: njs vs Lua vs Python vs Go vs Rust vs Bun vs Java vs Kotlin. A legenda enquadra a intenção: desempenho para cargas de trabalho longas de pesquisa/chat/fila/API - caminhos com muitas conexões, JSON e roteamento, em vez de uma única corrida de bigas do tipo “olá mundo”. As lojas JVM finalmente obtêm a mesma superfície justa que Go/Rust/Bun, em vez de uma anedota de “empresa” separada.
2.1 O que o painel mostra
Enquanto uma execução avança, a interface do usuário pesquisa /data/results.json a cada dois segundos e renderiza:
- Solicitações/seg (taxa de transferência) - agregado de
wrkpor idioma por teste - Latência média e Latência da cauda P99 – em milissegundos do modelo de latência do wrk
- TTFB (tempo até o primeiro byte) - do curl timing JSON ao lado do wrk
- Tabela de resumo — vencedores por teste com ★ marcadores nas melhores células
- Cartões de teste detalhados — gráficos de barras e tabelas métricas (P50, P90, P99.9, erros)
- Distribuição percentil de latência - média entre testes
- Veredicto – melhor para o seu caso de uso - narrativa uma vez que o status é
complete
Essa estrutura é deliberadamente compatível com ARB: gráficos para slides, tabelas para planilhas, narrativa para a seção de risco de um ADR.
3. O recurso de exemplos de fluxo de trabalho
Tudo o que é reproduzível vive sob benchmarks/ no exemplos de fluxo de trabalho repositório. Layout de nível superior:
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 Topologia Docker Compose
docker-compose.yml define serviços isolados em uma rede compartilhada:
nginx-njs— porta 8081, configurações de./njsopenresty-lua- porta 8082python-fastapi— porta 8084, construída a partir de./pythongo-server- porta 8085rust-actix- porta 8086bun-server- porta 8087java-server— porta 8088, Javalin / Jetty de./javakotlin-server— porta 8089, Ktor / Netty de./kotlindashboard— porta 8083, serve HTML e monta oresultsvolume em/databench— Contêiner alpino que instalacurl,wrk,jq, espera por dependências, executabench.sh
O corredor de banco compartilha o results volume com o painel para que os resultados apareçam ao vivo sem cópia manual.
3.2 metodologia bench.sh
O driver shell codifica regras de imparcialidade explicitamente:
- Duração:
10spor endpoint por idioma - Tópicos: 4
- Conexões: 100 simultâneos
- Aquecimento: 50 rodadas acertando
/helloem todos os servidores antes dos testes cronometrados - Por servidor: curl timing JSON (dns, connect, ttfb, total) mais wrk com
wrk_json.lua
Sete testes são delimitados por barras verticais no script:
| EU IA | Nome | Intenção | Ponto final |
|---|---|---|---|
| 1 | Texto Simples | Linha de base – resposta mínima, sobrecarga da estrutura | /hello |
| 2 | Serialização JSON | Construir e serializar array JSON de 100 itens | /json |
| 3 | Limite CPU (fib 30) | Fibonacci recursivo (30) - CPU puro | /cpu?n=30 |
| 4 | Manipulação de cordas | Construir, dividir, colocar letras maiúsculas e juntar novamente 1.000 segmentos | /string |
| 5 | Solicitar inspeção | Cabeçalhos, método, argumentos → JSON | /request_info?foo=bar&baz=123 |
| 6 | Subsolicitação + Transformação | Subsolicitação interna, analisar JSON, transformar | /subrequest |
| 7 | Lógica de roteamento | Roteamento condicional em parâmetros de consulta | /route?action=greet&name=bench |
Cada linguagem implementa a mesma superfície de rota (veja golang/main.go, python/main.py, java/, kotlin/, configurações NGINX, etc.) para que as diferenças reflitam o tempo de execução e a estrutura, e não especificações incompatíveis.
4. Por que “poliglota” é importante (sem fanatismo)
A arquitetura poliglota não significa que todo engenheiro aprenda oito idiomas. Isso significa contextos limitados obtenha um tempo de execução adequado:
- Plano de borda — autenticação, limites de taxa, roteamento: Lua ou njs dentro do NGINX você já opera
- Plano central API — lógica de negócios com SLOs: Go ou Rust
- Plano JVM — propriedades Spring/Jakarta existentes, bibliotecas compartilhadas, profundidade de contratação: Java (Javalin) ou Kotlin (Ktor)
- Plano de dados — ETL, notebooks, cola ML: Python
- Plano JS em tempo real — WebSockets, tipos compartilhados com frontend: Bun ou Node onde a velocidade vence
Pilhas uniformes otimizam o RH e as compras. Benchmarks poliglotas otimizam ajuste por carga de trabalho com compensações mensuráveis sobre a mesa.
5. Dimensões que importam
Req/s brutos é a métrica que viaja mais rápido no Slack. É também o mais fácil de interpretar mal. Use uma rubrica com várias colunas:
| Critério | Domina quando… | Sinal de chicote |
|---|---|---|
| latência p50/p99 | APIs voltados para o usuário, bate-papo, pesquisa longa | percentis de latência de trabalho; gráfico P99 do painel |
| Taxa de transferência (RPS) | Gateways de alta distribuição, agregadores em lote | trabalho RPS; coluna vencedora do resumo |
| Memória por conexão | Milhares de WebSockets ociosos | Perfil qualitativo + de produção (não totalmente aproveitado) |
| TTFB | Falta de CDN, caminhos frios, redes móveis | enrolar time_starttransfer nos resultados JSON |
| LOC/complexidade | Startups, controle de mudanças regulamentadas | Compare implementações entre pastas |
| Tempo de construção e CI | Implantações frequentes, muitos serviços | Docker constrói perfis por idioma |
| Carga operacional | Equipe de plataforma pequena | Habilidades NGINX existentes → Lua/njs; outros contêineres |
| Custo de hospedagem | Sempre ativo versus escala até zero | Derivado da memória + CPU sob carga (produção) |
6. Matriz de decisão
O diagrama abaixo é o mapa qualitativo que usamos nas análises – líderes ilustrativos, não um substituto para o uso do equipamento em seu kit.

Leia primeiro a linha: escolha o formato da carga de trabalho e, em seguida, pondere as colunas. Se dois critérios entrarem em conflito (por exemplo, melhor RPS versus menor LOC), essa tensão é a discussão sobre ADR que vale a pena ter.
7. Padrões de casos (exemplo de rotulagem)
Os mapas a seguir aproveitam as famílias de testes para escolhas arquitetônicas. Os líderes da sua máquina aparecem no painel após uma corrida — não trate esta seção como pontuações fixas.
7.1 API sensível à latência (Testes 1–2, 5–7)
JSON APIs e manipuladores com muito roteamento espelham os testes 2, 5 e 7. Tempos de execução assíncronos compilados (Rust Actix, Go) normalmente levam em taxa de transferência e latência final nesta classe de benchmarks HTTP sintéticos; Bun muitas vezes fica próximo de caminhos pesados de JSON com ergonomia JS. Java (Javalin) e Kotlin (Ktor) forneça às equipes de JVM uma leitura justa em relação aos líderes nas mesmas rotas — útil quando a questão é “permanecer na JVM com uma pilha mais leve” versus “reescrever em Go/Rust”. Python FastAPI troca RPS bruto por velocidade de desenvolvimento – o veredicto do painel indica isso explicitamente.
7.2 Microtrabalho vinculado ao CPU (Teste 3)
Fibonacci(30) isola CPU sem E/S. Espere a ferrugem e vá brilhar; pilhas interpretadas pagam despesas gerais; O JVM JIT pode parecer mais forte após o aquecimento do que uma janela fria de 10 segundos sugere - estenda a duração se esse for o seu perfil real. Se o seu serviço real estiver vinculado a E/S, não sobrecarregue esta linha - é um teste de estresse para middleware de computação pesada, não um CRUD típico.
7.3 Transformação de borda (testes 6–7, variantes NGINX)
Os testes de subsolicitação e roteamento são onde OpenResty Lua e NGINX njs pertencem: zero salto extra, memória de trabalho compartilhada, equipes de operações já gerenciam o NGINX. O veredicto do chicote recomenda Go/Rust para back-ends principais de chat/fila e Lua/njs na borda – uma divisão sensata que muitas empresas já administram informalmente.
7.4 ETL em lote e pipeline de dados
O chicote HTTP não emula cargas do Spark ou do warehouse. Para lote, as equipes geralmente priorizam o ecossistema Python e a orquestração (Airflow, Dagster) ou trabalhadores Go para produtividade. Use benchmarks poliglotas para o Superfícies API e planos de controle esses trabalhos expõem, não para o mecanismo de lote em si.
7.5 Ferramenta interna rápida
Administradores internos APIs com baixo QPS e alta taxa de alteração: Python ou Bun/Node geralmente ganham em velocidade e contratação. Execute o Teste 2 (JSON) e o Teste 5 (inspeção) para garantir que a sobrecarga seja aceitável; se o p99 atingir menos de 100 conexões, reconsidere antes de promover para camadas voltadas para o cliente.
7.6 Propriedade JVM (Java e Kotlin)
Muitas empresas já executam Java ou Kotlin para bibliotecas compartilhadas, ferramentas de conformidade e profundidade de contratação. O arnês java-server (Javalin em Jetty, porta 8088) e kotlin-server (Ktor em Netty, porta 8089) implementam os mesmos sete endpoints que Go e Rust, para que você possa quantificar se uma pilha JVM HTTP mais leve é “boa o suficiente” para um determinado SLO antes de reescrever. Prefira o Kotlin quando a simultaneidade no estilo corrotina e as equipes Kotlin-first forem importantes; prefira Java quando a propriedade circundante e o gráfico da biblioteca já forem centrados em Java. Use as linhas do painel ativo - não presuma que os números do Spring Boot sejam iguais aos números Javalin/Ktor.
8. Diagrama de fluxo de trabalho

O loop reproduzível: especifique a carga de trabalho → execute o chicote do Compose → publique os resultados no painel Fictionally (ou seu clone interno) → registre um ADR com metadados de configuração → execute novamente quando os tempos de execução ou o hardware mudarem.
9. Como fazer sua própria comparação
- Clone:
git clone https://github.com/bwalia/workflow-examples.git && cd workflow-examples/benchmarks - Pilha inicial:
docker compose up --build— cria todas as imagens de linguagem, inicia o painel na porta 8083, executa o bench automaticamente. - Assistir: abrir
http://localhost:8083(ou o site público quando uma execução hospedada está ativa). - Estender: adicionar uma pasta
myruntime/, espelhe caminhos de endpoint, registre um serviço emdocker-compose.yml, anexe o servidor aSERVERSembench.sh. - Personalizar carga: editar
DURATION,THREADS,CONNECTIONSno topo debench.sh— documentar alterações no seu ADR. - Adicione testes em formato de produção: por exemplo middleware de autenticação, consulta ORM, carga útil de 50 KB — mantenha a paridade entre idiomas.
Para CI, execute o Compose em um fluxo de trabalho noturno, arquive results.json como um artefato e falha apenas nos limites de regressão definidos (por exemplo, p99 +20% semana após semana no Teste 2).
10. Antipadrões
- Escolhendo o vencedor apenas do Teste 1 — o texto simples favorece pilhas mínimas; ele ignora JSON, CPU e problemas de roteamento.
- Ignorando as habilidades da equipe — A ferrugem na produção sem mentores custa caro em termos de incidentes.
- Ignorando o custo de hospedagem — 2× RPS é inútil se a memória por pod dobrar sua conta.
- Obrigação de um idioma em toda a organização - destrói divisões legítimas de borda versus núcleo.
- Substituindo o perfil de produção — HTTP sintético ≠ seu ORM, cache ou latência regional.
- Comparando hardware diferente — laptop Docker ≠ bare metal ≠ limites K8s; observe a classe no ADR.
11. Benefícios para a liderança em engenharia
- Pacotes ARB — exportar capturas de tela do painel +
results.json+ Compor hash. - Evidência neutra em relação ao fornecedor — nenhuma apresentação de vendas de um único fornecedor de nuvem ou estrutura.
- Clareza de integração — novas contratações vejam *por que* o serviço A é Go e o serviço B é Python.
- Redução de risco - pilotar o segundo colocado em um serviço paralelo antes de reescrever.
- Conversas sobre FinOps - vincule a latência final ao escalonamento automático e ao espaço de memória.
- Roteiro da plataforma - justifique o investimento em habilidades NGINX em comparação com outro microsserviço K8s.
12. Limitações
- Cargas de trabalho sintéticas — sete testes HTTP não podem representar consumidores Kafka, trabalhos GPU ou gráficos ORM complexos.
- Rede Docker — adiciona sobrecarga; os números absolutos diferem do metal puro.
- Classe de máquina única — os resultados hospedados refletem qualquer hardware usado ficcionalmente; seus números serão diferentes.
- Sem camada de persistência — os efeitos do banco de dados e do cache estão ausentes por design.
- Duração curta — 10s por teste não podem expor pausas do GC ou interrupções no aquecimento; estender para campanhas de estresse.
Mantenha o perfil contínuo (eBPF, APM, testes de carga contra preparação) como a fonte da verdade para a produção. Benchmarks poliglotas restringem o linguagem e estrutura debate com linhas de base reproduzíveis.
13. Conclusão
A polarização da pilha padrão é confortável; é também como as equipes fornecem o tempo de execução errado para o trabalho. Benchmarks poliglotas e o exemplos de fluxo de trabalho aproveitar a vez “qual idioma vence?” em “qual idioma vence para esta linha de carga de trabalho?” – com gráficos que seu ARB pode citar.
Bifurque o repositório, adicione os endpoints que se parecem com seus hot paths, execute o Compose e anexe os resultados à próxima decisão de arquitetura. O companheiro postagem no blog é a versão de cinco minutos para compartilhar; este artigo é a referência.
Publicado por Workstation (workstation.co.uk). Painel de referência hospedado em polyglot-benchmarks.fictionally.org no ecossistema de exemplos ficcionais.
Instantâneo de SEO para este artigo
- Título SEO: Benchmarks poliglotas: ferramenta certa para o trabalho
- Meta descrição: Compare njs, Lua, Python, Go, Rust, Bun, Java e Kotlin nas mesmas cargas de trabalho HTTP. Arnês reproduzível, painel ao vivo, matriz de decisão para arquitetos.
- Palavras-chave primárias: benchmarks poliglotas, comparação de linguagens, decisões de arquitetura, exemplos de fluxo de trabalho, benchmark de desempenho, Rust vs Go, Java vs Kotlin, FastAPI, Javalin, Ktor
- Twitter / X (menos de 280 caracteres): Benchmarks poliglotas: os mesmos 7 testes HTTP em njs, Lua, Python, Go, Rust, Bun, Java, Kotlin - painel ao vivo + aproveitamento de exemplos de fluxo de trabalho. Nenhum vencedor; um quadro de decisão. #Rust #GoLang #Java #Kotlin #Bunjs #poliglota
- Postagem no LinkedIn: Publicamos um mergulho profundo nos benchmarks poliglotas – como parar de escolher uma pilha para toda a organização por hábito e começar a combinar tempos de execução com cargas de trabalho. Oito linguagens (incluindo Java/Javalin e Kotlin/Ktor), sete testes comparáveis, Docker Compose + wrk, resultados ao vivo em polyglot-benchmarks.ficctionally.org, fonte em github.com/bwalia/workflow-examples/tree/main/benchmarks. Inclui matriz de decisão, antipadrões e orientação de ADR. Da engenharia Workstation. #Rust #GoLang #Java #Kotlin #Bunjs #Lua #Python #njs #FastAPI #Javalin #Ktor #OpenResty #polyglot #benchmarks