Reduzindo o Tamanho do Binário
Binários Rust podem crescer em tamanho devido à monomorfização e símbolos de depuração. Remova símbolos, ajuste opt-level, desabilite recursos não utilizados e use panic = abort para artefatos de implantação menores.
Receita
[profile.release]
opt-level = "z"
lto = true
panic = "abort"
strip = "symbols"cargo bloat --release --cratesQuando usar isso: Distribuição de CLI, alvos embarcados, bundles WASM e otimização de imagens de contêiner.
Exemplo de Trabalho
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = "symbols"
[features]
default = []cargo build --release
ls -lh target/release/myapp
cargo bloat --release -n 30O que isso demonstra:
opt-level = "z"otimiza para tamanho em vez de velocidade- O mínimo de recursos padrão reduz o código compilado
cargo bloatmostra as maiores funções/cratesstripremove tabelas de símbolos do binário enviado
Mergulho Profundo
Alavancas de Tamanho
| Alavanca | Efeito |
|---|---|
| Menos recursos em dependências | Menos código vinculado |
panic = abort | Sem tabelas de desenrolamento (unwinding) |
strip | Menor em disco |
| Vinculação dinâmica (plataforma) | Raro em servidores Rust |
Compressão upx | Último recurso, problemas de AV |
Tamanho do WASM
[profile.release]
opt-level = "s"Execute wasm-opt -Oz após a compilação para alvos WASM.
Armadilhas
- Otimização de tamanho sem verificação de desempenho - regressão de latência na API. Correção: faça benchmark dos caminhos críticos após a otimização de tamanho.
- Manter todos os recursos padrão - puxa o tokio completo quando apenas
rté necessário. Correção:default-features = false. - Muitas instanciações genéricas - código duplicado. Correção: apagamento de tipo apenas em caminhos "frios" (cold paths).
- Símbolos de depuração no Docker - camadas enormes. Correção: remova na etapa final ou em um pacote de símbolos de depuração separado.
abortde panics em bibliotecas - os consumidores não podem capturar. Correção: aplicativos escolhempanic = abort; bibliotecas geralmenteunwind.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
opt-level = "s" | Equilíbrio tamanho/velocidade | Necessidade extrema de tamanho |
split-debuginfo | Manter símbolos fora do binário | Necessidade de depuração em arquivo único |
| Binário estático musl | CLI portátil | Nuances de DNS do glibc |
FAQs
Qual tamanho é considerado muito grande?
Depende do contexto: CLI < poucos MB é ideal; servidor é menos crítico que a contagem de contêineres de dependências.
LTO ajuda no tamanho?
Sim, mescla e remove código morto de funções não utilizadas entre crates.
Por que o tokio é grande?
Habilite apenas os recursos necessários: rt-multi-thread, macros, não o completo a menos que seja exigido.
Tamanho do clap?
Use clap 4 com derive e desabilite recursos de string não utilizados; considere argh para CLIs minúsculas.
serde no binário?
Necessário para APIs JSON; evite derivar em todos os tipos internos se não forem serializados.
strip vs split debuginfo?
strip para artefato mínimo; split para relatórios de falha com símbolos externos.
Tamanho do binário WASM?
wasm-pack build --release + wasm-opt; evite puxar o std completo quando possível.
Tamanho estático musl?
Às vezes maior que glibc dinâmico; troque portabilidade por MB.
Contar monomorfização?
cargo bloat mostra instanciações; reduza tipos genéricos na superfície de crates "quentes" (hot crates).
Docker distroless?
Imagem de runtime pequena complementa o binário Rust com strip; ainda assim, minimize o binário em si.
Relacionados
- Ajuste de Release - perfis de desempenho vs. tamanho
- Perfis e Configurações de Compilação
- Subcomandos Úteis do Cargo - bloat
- Imagens Mínimas do Docker
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.