Solo por haber encontrado Rust y haber leído los dos primeros capítulos de la documentación, encuentro el enfoque y la forma en que definieron el lenguaje particularmente interesante. Así que decidí mojarme los dedos y comencé con Hello world ...
Lo hice en Windows 7 x64, por cierto.
fn main() {
println!("Hello, world!");
}
Emitiendo cargo build
y mirando el resultado targets\debug
, encontré que el resultado .exe
es 3MB. Después de algunas búsquedas (la documentación de las banderas de línea de comando de carga es difícil de encontrar ...) encontré la --release
opción y creé la versión de lanzamiento. Para mi sorpresa, el tamaño .exe solo se ha reducido en una cantidad insignificante: 2.99MB en lugar de 3MB.
Entonces, confesando que soy un novato en Rust y su ecosistema, mi expectativa habría sido que un lenguaje de programación de sistemas produciría algo compacto.
¿Alguien puede dar más detalles sobre qué está compilando Rust, cómo puede ser posible que produzca imágenes tan grandes de un programa de 3 líneas? ¿Se está compilando en una máquina virtual? ¿Hay un comando de tira que me perdí (información de depuración dentro de la compilación de lanzamiento)? ¿Algo más que pueda permitir entender lo que está pasando?
fuente
Respuestas:
Rust utiliza enlaces estáticos para compilar sus programas, lo que significa que todas las bibliotecas requeridas incluso por el
Hello world!
programa más simple se compilarán en su ejecutable. Esto también incluye el tiempo de ejecución de Rust.Para forzar a Rust a vincular dinámicamente programas, use los argumentos de la línea de comandos
-C prefer-dynamic
; esto dará como resultado un tamaño de archivo mucho más pequeño, pero también requerirá que las bibliotecas Rust (incluido su tiempo de ejecución) estén disponibles para su programa en tiempo de ejecución. Esto significa esencialmente que deberá proporcionarlos si la computadora no los tiene, ocupando más espacio del que ocupa su programa original vinculado estáticamente.Para la portabilidad, le recomiendo que enlace estáticamente las bibliotecas Rust y el tiempo de ejecución de la forma en que lo ha estado haciendo si alguna vez distribuyera sus programas a otros.
fuente
cargo rustc [--debug or --release] -- -C prefer-dynamic
No tengo ningún sistema de Windows para probar, pero en Linux, un mundo de Rust hello compilado estáticamente es en realidad más pequeño que el equivalente C. Si está viendo una gran diferencia de tamaño, probablemente sea porque está vinculando el ejecutable de Rust estáticamente y el C dinámicamente.
Con el enlace dinámico, también debe tener en cuenta el tamaño de todas las bibliotecas dinámicas, no solo el ejecutable.
Entonces, si desea comparar manzanas con manzanas, debe asegurarse de que ambas sean dinámicas o ambas sean estáticas. Los diferentes compiladores tendrán valores predeterminados diferentes, por lo que no puede confiar solo en los valores predeterminados del compilador para producir el mismo resultado.
Si estás interesado, aquí están mis resultados:
Estos fueron compilados con gcc (Debian 4.9.2-10) 4.9.2 y rustc 1.0.0-nightly (d17d6e7f1 2015-04-02) (construido 2015-04-03), ambos con opciones predeterminadas y con
-static
gcc y-C prefer-dynamic
para rustc.Tenía dos versiones del mundo C hello porque pensé que usar
puts()
podría enlazar en menos unidades de compilación.Si quieres intentar reproducirlo en Windows, estas son las fuentes que utilicé:
printf.c:
puts.c:
rust.rs
Además, tenga en cuenta que diferentes cantidades de información de depuración o diferentes niveles de optimización también marcarían la diferencia. Pero espero que si ves una gran diferencia se deba a la vinculación estática frente a la dinámica.
fuente
strip -s
, cae de 1.6M a 190K. La versión de lanzamiento (valores predeterminados másopt-level='s'
,lto = true
ypanic = 'abort'
para minimizar el tamaño) cae de 623K a 158K.Al compilar con Cargo, puede usar la vinculación dinámica:
Esto reducirá drásticamente el tamaño del binario, ya que ahora está vinculado dinámicamente.
En Linux, al menos, también puede quitar el binario de símbolos con el
strip
comando:Esto reducirá aproximadamente a la mitad el tamaño de la mayoría de los binarios.
fuente
Para obtener una descripción general de todas las formas de reducir el tamaño de un binario Rust, consulte el
min-sized-rust
repositorio.Los pasos actuales de alto nivel para reducir el tamaño binario son:
jemalloc
por defecto)Cargo.toml
cargo build --release
strip
en el binario resultante.Se puede hacer más con
nightly
Rust, pero dejaré esa información amin-sized-rust
medida que cambie con el tiempo debido al uso de características inestables.También puedes usar
#![no_std]
para eliminar Rust'slibstd
. Vermin-sized-rust
para más detalles.fuente
¡Esto es una característica, no un error!
Puede especificar las versiones de la biblioteca (en el archivo Cargo.toml asociado al proyecto ) utilizadas en el programa (incluso las implícitas) para garantizar la compatibilidad de la versión de la biblioteca. Esto, por otro lado, requiere que la biblioteca específica esté vinculada estáticamente al ejecutable, generando grandes imágenes en tiempo de ejecución.
Hola, ya no es 1978, muchas personas tienen más de 2 MB de RAM en sus computadoras :-)
fuente