Baru saja menemukan Rust dan setelah membaca dua bab pertama dari dokumentasi, saya menemukan pendekatan dan cara mereka mendefinisikan bahasa sangat menarik. Jadi saya memutuskan untuk membasahi jari saya dan mulai dengan Hello world ...
Saya melakukannya pada Windows 7 x64, btw.
fn main() {
println!("Hello, world!");
}
Mengeluarkan cargo build
dan melihat hasilnya targets\debug
saya menemukan hasilnya .exe
3MB. Setelah beberapa pencarian (dokumentasi bendera baris perintah kargo sulit ditemukan ...) Saya menemukan --release
opsi dan membuat rilis rilis. Yang mengejutkan saya, ukuran .exe hanya menjadi lebih kecil dengan jumlah yang tidak signifikan: 2.99MB bukannya 3MB.
Jadi, mengakui saya seorang pemula untuk Rust dan ekosistemnya, harapan saya adalah bahwa bahasa Pemrograman Sistem akan menghasilkan sesuatu yang kompak.
Adakah yang bisa menguraikan tentang apa yang dikompilasi oleh Rust, bagaimana mungkin ia menghasilkan gambar sebesar itu dari program 3 liner? Apakah kompilasi ke mesin virtual? Apakah ada perintah strip yang saya lewatkan (info debug di dalam rilis rilis?)? Ada hal lain yang memungkinkan untuk memahami apa yang sedang terjadi?
sumber
Jawaban:
Rust menggunakan tautan statis untuk mengkompilasi program-programnya, artinya semua perpustakaan yang dibutuhkan oleh
Hello world!
program paling sederhana pun akan dikompilasi ke dalam executable Anda. Ini juga termasuk runtime Rust.Untuk memaksa Rust menautkan program secara dinamis, gunakan argumen baris perintah
-C prefer-dynamic
; ini akan menghasilkan ukuran file yang jauh lebih kecil tetapi juga akan membutuhkan pustaka Rust (termasuk runtime-nya) agar tersedia untuk program Anda saat runtime. Ini pada dasarnya berarti Anda harus menyediakannya jika komputer tidak memilikinya, menghabiskan lebih banyak ruang daripada waktu yang dihabiskan oleh program yang terhubung secara statis.Untuk portabilitas, saya sarankan Anda secara statis menghubungkan perpustakaan Rust dan runtime dengan cara yang telah Anda lakukan jika Anda pernah mendistribusikan program Anda kepada orang lain.
sumber
cargo rustc [--debug or --release] -- -C prefer-dynamic
Saya tidak memiliki sistem Windows untuk dicoba, tetapi di Linux, dunia halo yang dikompilasi secara statis sebenarnya lebih kecil daripada yang setara dengan C. Jika Anda melihat perbedaan besar dalam ukuran, itu mungkin karena Anda menghubungkan Rust yang dapat dieksekusi statis dan C satu secara dinamis.
Dengan tautan dinamis, Anda perlu mempertimbangkan ukuran semua perpustakaan dinamis juga, bukan hanya yang dapat dieksekusi.
Jadi, jika Anda ingin membandingkan apel dengan apel, Anda harus memastikan keduanya dinamis atau keduanya statis. Kompiler yang berbeda akan memiliki default yang berbeda, jadi Anda tidak bisa hanya mengandalkan default kompiler untuk menghasilkan hasil yang sama.
Jika Anda tertarik, inilah hasil saya:
Ini dikompilasi dengan gcc (Debian 4.9.2-10) 4.9.2 dan rustc 1.0.0-nightly (d17d6e7f1 2015-04-02) (dibangun 2015-04-03), keduanya dengan opsi default dan dengan
-static
untuk gcc dan-C prefer-dynamic
untuk rustc.Saya memiliki dua versi C hello world karena saya pikir menggunakan
puts()
tautan mungkin dalam unit kompilasi yang lebih sedikit.Jika Anda ingin mencoba mereproduksinya di Windows, berikut adalah sumber yang saya gunakan:
printf.c:
puts.c:
rust.rs
Juga, ingatlah bahwa jumlah informasi debug yang berbeda, atau tingkat optimisasi yang berbeda juga akan membuat perbedaan. Tapi saya berharap jika Anda melihat perbedaan besar itu karena tautan statis dan dinamis.
sumber
strip -s
, turun dari 1.6M ke 190K. Rilis membangun (default ditambahopt-level='s'
,lto = true
danpanic = 'abort'
untuk meminimalkan ukuran) turun dari 623K ke 158K.Saat kompilasi dengan Cargo, Anda dapat menggunakan tautan dinamis:
Ini secara dramatis akan mengurangi ukuran biner, karena sekarang terkait secara dinamis.
Di Linux, setidaknya, Anda juga dapat menghapus biner simbol menggunakan
strip
perintah:Ini kira-kira akan membagi dua ukuran sebagian besar binari.
sumber
Untuk ikhtisar semua cara untuk mengurangi ukuran biner Rust, lihat
min-sized-rust
repositori.Langkah-langkah tingkat tinggi saat ini untuk mengurangi ukuran biner adalah:
jemalloc
secara default)Cargo.toml
cargo build --release
strip
pada biner yang dihasilkan.Ada banyak hal yang dapat dilakukan dengan menggunakan
nightly
Rust, tetapi saya akan membiarkan informasimin-sized-rust
itu karena akan berubah seiring waktu karena penggunaan fitur yang tidak stabil.Anda juga dapat menggunakan
#![no_std]
untuk menghapus Rustlibstd
. Lihatmin-sized-rust
detailnya.sumber
Ini adalah fitur, bukan bug!
Anda dapat menentukan versi perpustakaan (dalam file Cargo.toml terkait proyek ) yang digunakan dalam program (bahkan yang implisit) untuk memastikan kompatibilitas versi perpustakaan. Ini, di sisi lain, mensyaratkan bahwa perpustakaan tertentu secara statis dihubungkan dengan yang dapat dieksekusi, menghasilkan gambar run-time yang besar.
Hei, ini bukan 1978 lagi - banyak orang memiliki lebih dari 2 MB RAM di komputer mereka :-)
sumber