Saya mematuhi program hello world Go yang menghasilkan executable asli di mesin linux saya. Tapi saya terkejut melihat ukuran program Hello world Go yang sederhana, yaitu 1.9MB!
Mengapa program yang bisa dieksekusi di Go begitu besar?
go
executable
Karthic Rao
sumber
sumber
dotnet publish -r win-x64 -p:publishsinglefile=true -p:publishreadytorun=true -p:publishtrimmed=true
menghasilkan file biner sekitar ~ 26MB!Jawaban:
Pertanyaan persis ini muncul di FAQ resmi: Mengapa program sepele saya memiliki biner yang begitu besar?
Mengutip jawabannya:
Jadi executable asli Hello World Anda adalah 1,9 MB karena berisi runtime yang menyediakan pengumpulan sampah, refleksi, dan banyak fitur lainnya (yang mungkin tidak benar-benar digunakan oleh program Anda, tetapi program itu ada di sana). Dan implementasi
fmt
paket yang Anda gunakan untuk mencetak"Hello World"
teks (ditambah dependensinya).Sekarang coba yang berikut ini: tambahkan
fmt.Println("Hello World! Again")
baris lain ke program Anda dan kompilasi lagi. Hasilnya bukan 2x 1.9MB, tapi tetap hanya 1.9 MB! Ya, karena semua pustaka yang digunakan (fmt
dan dependensinya) dan runtime sudah ditambahkan ke file yang dapat dieksekusi (sehingga hanya beberapa byte lagi yang akan ditambahkan untuk mencetak teks ke-2 yang baru saja Anda tambahkan).sumber
Pertimbangkan program berikut:
package main import "fmt" func main() { fmt.Println("Hello World!") }
Jika saya membangun ini di mesin Linux AMD64 saya (Go 1.9), seperti ini:
$ go build $ ls -la helloworld -rwxr-xr-x 1 janf group 2029206 Sep 11 16:58 helloworld
Saya mendapatkan biner berukuran sekitar 2 Mb.
Alasan untuk ini (yang telah dijelaskan di jawaban lain) adalah karena kami menggunakan paket "fmt" yang cukup besar, tetapi binernya juga belum dihapus dan ini berarti tabel simbol masih ada. Jika kita menginstruksikan kompilator untuk menghapus biner, itu akan menjadi jauh lebih kecil:
$ go build -ldflags "-s -w" $ ls -la helloworld -rwxr-xr-x 1 janf group 1323616 Sep 11 17:01 helloworld
Namun, jika kita menulis ulang program untuk menggunakan fungsi cetak bawaan, daripada fmt.Println, seperti ini:
package main func main() { print("Hello World!\n") }
Dan kemudian kompilasi:
$ go build -ldflags "-s -w" $ ls -la helloworld -rwxr-xr-x 1 janf group 714176 Sep 11 17:06 helloworld
Kami berakhir dengan biner yang lebih kecil. Ini sekecil yang bisa kita dapatkan tanpa menggunakan trik seperti pengemasan UPX, jadi overhead waktu proses Go kira-kira 700 Kb.
sumber
Perhatikan bahwa masalah ukuran biner dilacak oleh masalah 6853 di proyek golang / go .
Misalnya, lakukan a26c01a (untuk Go 1.4) potong hello world sebesar 70kB :
Mengingat compiler, assembler, linker, dan runtime untuk 1.5 akan sepenuhnya ada di Go, Anda dapat mengharapkan pengoptimalan lebih lanjut.
Update 2016 Go 1.7: ini telah dioptimalkan: lihat " Smaller Go 1.7 binaries ".
Tapi hari ini (April 2019), yang paling banyak terjadi adalah
runtime.pclntab
.Lihat " Mengapa file Go saya yang dapat dieksekusi begitu besar? Visualisasi ukuran file yang dapat dieksekusi Go menggunakan D3 " dari Raphael 'kena' Poss .
sumber