Tendo encontrado Rust e tendo lido os dois primeiros capítulos da documentação, acho a abordagem e a maneira como eles definiram a linguagem particularmente interessante. Então eu decidi molhar meus dedos e comecei com Hello world ...
Eu fiz isso no Windows 7 x64, aliás.
fn main() {
println!("Hello, world!");
}
Emitindo cargo build
e analisando o resultado targets\debug
, encontrei o resultado .exe
sendo 3 MB. Após algumas pesquisas (é difícil encontrar a documentação das bandeiras da linha de comando de carga ...), encontrei a --release
opção e criei a versão build. Para minha surpresa, o tamanho do .exe ficou menor em uma quantidade insignificante: 2,99 MB em vez de 3 MB.
Então, confessando que sou novato no Rust e em seu ecossistema, minha expectativa seria que uma linguagem de programação de sistemas produzisse algo compacto.
Alguém pode elaborar sobre o que o Rust está compilando, como é possível que produza imagens tão grandes a partir de um programa de 3 linhas? Está compilando em uma máquina virtual? Existe um comando strip que eu perdi (informações de depuração dentro da compilação do release?)? Mais alguma coisa que permita entender o que está acontecendo?
fonte
Respostas:
O Rust usa o link estático para compilar seus programas, o que significa que todas as bibliotecas exigidas pelo
Hello world!
programa mais simples serão compiladas no seu executável. Isso também inclui o tempo de execução do Rust.Para forçar o Rust a vincular dinamicamente programas, use os argumentos da linha de comando
-C prefer-dynamic
; isso resultará em um tamanho de arquivo muito menor, mas também exigirá que as bibliotecas Rust (incluindo seu tempo de execução) estejam disponíveis para o seu programa em tempo de execução. Isso significa essencialmente que você precisará fornecê-los se o computador não os possuir, ocupando mais espaço do que o programa vinculado estaticamente original ocupa.Para portabilidade, eu recomendo que você vincule estaticamente as bibliotecas e o tempo de execução do Rust da maneira que está fazendo, se quiser distribuir seus programas a outras pessoas.
fonte
cargo rustc [--debug or --release] -- -C prefer-dynamic
Não tenho nenhum sistema Windows para testar, mas no Linux, um mundo Rust hello compilado estaticamente é realmente menor que o equivalente a C. Se você está vendo uma enorme diferença de tamanho, provavelmente é porque está vinculando o executável Rust estaticamente e o C dinamicamente.
Com a vinculação dinâmica, você precisa levar em consideração o tamanho de todas as bibliotecas dinâmicas, não apenas o executável.
Portanto, se você quiser comparar maçãs com maçãs, verifique se as duas são dinâmicas ou estáticas. Compiladores diferentes terão padrões diferentes, então você não pode confiar apenas nos padrões do compilador para produzir o mesmo resultado.
Se você estiver interessado, aqui estão meus resultados:
Eles foram compilados com o gcc (Debian 4.9.2-10) 4.9.2 e rustc 1.0.0-nightly (d17d6e7f1 2015-04-02) (compilado em 2015-04-03), ambos com opções padrão e com o
-static
gcc e-C prefer-dynamic
para rustc.Eu tinha duas versões do mundo C hello, porque pensei que o uso
puts()
poderia estar vinculado em menos unidades de compilação.Se você quiser tentar reproduzi-lo no Windows, aqui estão as fontes que eu usei:
printf.c:
puts.c:
rust.rs
Além disso, lembre-se de que diferentes quantidades de informações de depuração ou diferentes níveis de otimização também fazem diferença. Mas espero que, se você vê uma enorme diferença, seja devido à vinculação estática versus dinâmica.
fonte
strip -s
, cai de 1.6M para 190K. A compilação do release (padrões maisopt-level='s'
,lto = true
epanic = 'abort'
para minimizar o tamanho) cai de 623K para 158K.Ao compilar com o Cargo, você pode usar o vínculo dinâmico:
Isso reduzirá drasticamente o tamanho do binário, pois agora está vinculado dinamicamente.
No Linux, pelo menos, você também pode remover o binário de símbolos usando o
strip
comando:Isso reduzirá pela metade o tamanho da maioria dos binários.
fonte
Para uma visão geral de todas as maneiras de reduzir o tamanho de um binário Rust, consulte o
min-sized-rust
repositório.As etapas atuais de alto nível para reduzir o tamanho binário são:
jemalloc
por padrão)Cargo.toml
cargo build --release
strip
no binário resultante.É possível fazer mais usando o
nightly
Rust, mas deixarei essas informaçõesmin-sized-rust
como elas mudam ao longo do tempo devido ao uso de recursos instáveis.Você também pode usar
#![no_std]
para remover o Rust'slibstd
. Vejamin-sized-rust
para detalhes.fonte
Este é um recurso, não um bug!
Você pode especificar as versões da biblioteca (no arquivo Cargo.toml associado ao projeto ) usadas no programa (mesmo as implícitas) para garantir a compatibilidade da versão da biblioteca. Por outro lado, isso requer que a biblioteca específica seja vinculada estaticamente ao executável, gerando imagens grandes em tempo de execução.
Ei, não é mais 1978 - muitas pessoas têm mais de 2 MB de RAM em seus computadores :-)
fonte