Comparativo Performance Linguagens
Comparativo de performance entre 8 linguagens em 11 provas, tudo validado em Docker: Rust, C++, Go, Java, Kotlin, Dart (Flutter), PHP com JIT e Python (CPython/PyPy).
#Comparativo de performance: 8 linguagens, 11 cenários, tudo em Docker
Bateria de benchmarks que compara Rust, C++, Go, Java, Kotlin, Dart (Flutter), PHP com JIT e Python (CPython e PyPy) em onze cargas de trabalho diferentes — do laço numérico puro ao motor de casamento de ordens com latência medida em nanossegundos.
Tudo roda em contêiner, com todas as versões pinadas e todas as imagens no mesmo Debian 13 "trixie" — misturar Alpine (musl) com slim (glibc) troca o alocador no meio da comparação e invalida qualquer conclusão sobre memória.
📄 O relatório completo, com a análise de cada prova, sai em PDF:
python3 gerar_pdf_relatorio.py.
#O placar
| Colocação | Linguagem | Soma das posições | 1º lugar em | Pior posição | Memória somada |
|---|---|---|---|---|---|
| 🥇 | Rust 1.98.0 | 19 | 8 de 11 | 5º | 753 MB |
| 🥈 | C++ (GCC 16.2) | 42 | 2 | 9º | 1 494 MB |
| 🥉 | Java 26 | 43 | 1 | 7º | 2 373 MB |
| 4º | Go 1.27.1 | 47 | — | 7º | 919 MB |
| 5º | Kotlin 2.4.20 | 52 | — | 8º | 2 467 MB |
| 6º | Dart 3.13.3 AOT (Flutter) | 63 | — | 8º | 1 388 MB |
| 7º | PHP 8.5.10 (JIT) | 64 | — | 8º | 2 224 MB |
| 8º | Python — PyPy 7.3.23 (JIT) | 75 | — | 9º | 2 392 MB |
| 9º | Python 3.14.7 (CPython) | 90 | — | 9º | 1 896 MB |
Medido num Intel i7-10700 (8 núcleos / 16 threads), 31 GB de RAM, Linux 6.x, Docker 29.7. Os seus números vão ser outros — o que deve se repetir são as proporções.
#As onze provas
| # | Prova | O que mede |
|---|---|---|
| T01 | Mandelbrot | Laço numérico puro: ponto flutuante e desvio imprevisível |
| T02 | Crivo de Eratóstenes | Inteiros e varredura sequencial de memória |
| T03 | Alocação | 5 milhões de objetos curtos: alocador e coletor de lixo |
| T04 | Tabela hash | 3 M de inserções + 3 M de buscas com chave textual |
| T05 | Ordenação | 10 M de inteiros de 64 bits com a função padrão |
| T06 | JSON (55 MB) | Desserializar, agregar e serializar de novo |
| T07 | XML (33 MB) | Leitura em fluxo com agregação por atributo |
| T08 | Expressão regular | 1 M de linhas de log: casar, extrair e agregar |
| T09 | Paralelismo | O mesmo Mandelbrot em 8 núcleos |
| T10 | Motor de casamento | 10 M de ordens com latência p50/p99/p99.9 por ordem |
| T11 | Partida a frio | Tempo e memória de só o runtime existir |
#Como rodar
Requisitos: Docker e Python 3 no host (o resto vive em contêiner).
# 1. baixa as dependências e gera as entradas (~225 MB, semente fixa) ./preparar.sh # 2. constrói as imagens — versões pinadas cd docker for f in rust cpp go jvm dart php pypy cpython cpythonjit; do docker build -t "bench-$f:1" -f "Dockerfile.$f" . done cd .. # 3. compila as implementações docker run --rm -v "$PWD":/bench -w /bench/src/rust bench-rust:1 cargo build --release docker run --rm -v "$PWD":/bench bench-cpp:1 /bench/compilar_cpp.sh docker run --rm -v "$PWD":/bench bench-go:1 /bench/compilar_go.sh docker run --rm -v "$PWD":/bench bench-dart:1 /bench/compilar_dart.sh docker run --rm -v "$PWD":/bench bench-jvm:1 sh -c 'cd /bench/src/java && javac -cp "lib/*" -d bin *.java' docker run --rm -v "$PWD":/bench bench-jvm:1 sh -c 'cd /bench/src/kotlin && kotlinc -cp "../java/lib/jackson-databind.jar:../java/lib/jackson-core.jar:../java/lib/jackson-annotations.jar" -d bin *.kt' # 4. roda a bateria (uma a duas horas; o CPython puro é o gargalo) python3 harness.py # 5. monta as tabelas python3 montar_tabelas.py
Dá para rodar só uma linguagem ou só uma prova:
python3 harness.py go # só o Go, nas 11 provas python3 harness.py go,rust t10_matching # Go e Rust, só no motor de casamento
#⚠️ Antes de medir qualquer coisa
Confira a carga da máquina: uptime. Acima de 1,5 de média, não meça. Na primeira tentativa
desta bateria o PyPy marcou 4,42 s no Mandelbrot com uma compilação rodando ao lado e 1,63 s com a
máquina livre — 2,7× de diferença que não tem nada a ver com a linguagem.
#As regras que tornam a comparação honesta
- Mesmo algoritmo em todas. Nada de trocar o crivo por uma fatiação esperta em Python ou por SIMD explícito em C++;
- Checksum obrigatório. As 9 implementações de cada prova imprimem um checksum, e os checksums batem. Sem isso, o comparativo mediria quem faz menos trabalho;
- A biblioteca padrão de cada uma, ou o padrão de fato do ecossistema — é assim que um projeto real nasce;
- Sem
-march=nativee sem afinar o coletor. Nada deGOGC,-Xmxou troca de alocador: cada runtime roda como sai da caixa; - Todo código dentro de função. O JIT do PHP otimiza corpo de função muito melhor que código no topo do script — eram 3,3× de penalidade num erro da primeira versão;
- Empate no tempo desempata pela menor memória. O
/usr/bin/timereporta duas casas decimais; duas linguagens que fazem o mesmo trabalho no mesmo tempo não estão empatadas se uma gasta 39 MB e a outra 2 MB; - Mediana de até três execuções, com tempo e pico de RSS medidos pelo
/usr/bin/timedentro do contêiner — o custo de subir o contêiner não entra na conta.
#O que este laboratório NÃO mede
- Rede, disco, banco e concorrência de E/S. Um servidor web real passa a maior parte da vida esperando o banco; nesse regime as diferenças encolhem muito. Isso é especialmente injusto com o Go, cuja maior força — dezenas de milhares de goroutines bloqueadas em E/S — nenhuma prova exercita;
- Produtividade, tempo de compilação, custo de contratação, maturidade de biblioteca — que decidem projeto mais vezes do que microssegundos.
#Estrutura
. ├── docker/ 9 Dockerfiles, um por runtime, com a versão pinada ├── src/ as 9 implementações de cada uma das 11 provas │ ├── rust/ cpp/ go/ java/ kotlin/ dart/ php/ python/ ├── dados/ gerado pelo preparar.sh (não versionado) ├── preparar.sh baixa dependências e gera as entradas ├── gerar_dados.py regera as entradas com semente fixa (42) ├── harness.py executa a bateria e grava resultados/resultados.json ├── montar_tabelas.py monta as tabelas do relatório ├── montar_anexo.py monta o anexo com uma linha por (prova × linguagem) └── resultados/ resultados.json, execucao.log e as tabelas
#Achou um erro?
Ótimo — abra uma issue. Este laboratório já teve três erros corrigidos depois de publicado (máquina carregada, PHP fora de função, desempate sem critério de memória), todos encontrados relendo os próprios números. Benchmark que ninguém contesta é benchmark que ninguém leu.
#👨💻 Créditos
Icaro William — Tio Jobs · Arquiteto de Software 🐙 github.com/icarojobs · 🎓 Jobs Treinamentos
Material de apoio do curso Principal/Senior Rust Engineer.