Golang 使用 upx 減少可執行文件的大小

衆所周知,Golang 的編譯速度是非常之快的。在設計 Go 時,編譯速度是一個重要的考慮因素。但是,你是否關注過 Go 編譯代碼後生成的二進制可執行文件的大小?讓我們來看一個簡單的 HTTP 服務的應用示例:

import (  
     "fmt"  
     "net/http"
 )  
 func main() {  
     // create a http server and create a handler hello, return hello world  
     http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {  
         fmt.Fprintf(w, "Hello, World\n")  
     })  
     // listen to port 8080  
     err := http.ListenAndServe(":8080", nil)  
     if err != nil {  
         return  
     }  
 }

編譯後的大小爲 6.5M。

➜  binary-size git:(main) ✗ go build  -o server main.go                 
 ➜  binary-size git:(main) ✗ ls -lh server 
 -rwxr-xr-x  1   staff   6.5M Jul  2 14:20 server

現在,讓我們嘗試優化上面應用的大小。

刪除調試信息

默認情況下,Go 編譯器會在編譯後的程序中包含符號表和調試信息。通常情況下,你可以在發佈版本中移除這些調試信息,以減小二進制文件的大小。

➜  binary-size git:(main) ✗ go build -ldflags="-s -w" -o server main.go
 ➜  binary-size git:(main) ✗ ls -lh server                              
 -rwxr-xr-x  1 hxzhouh  staff   4.5M Jul  2 14:30 server

使用 UPX

UPX[1] is an advanced executable file compressor. UPX will typically reduce the file size of programs and DLLs by around 50%-70%, thus reducing disk space, network load times, download times, and other distribution and storage costs.

UPX 是一種先進的可執行文件壓縮器。UPX 通常能將程序和 DLL 文件的大小減少 50%-70%,從而減少磁盤空間、網絡加載時間、下載時間以及其他分發和存儲成本。

在 Mac 上,你可以通過 brew 安裝 UPX。

brew install upx

僅使用 UPX 壓縮

UPX 有很多參數,其中最重要的是壓縮率,範圍從 1 到 13。讓我們看看僅使用 UPX 就能將二進制文件大小縮小多少。

➜  binary-size git:(main) ✗ go build -o server main.go && upx --brute server && ls -lh server 
 -rwxr-xr-x  1 hxzhouh  staff   3.9M Jul  2 14:38 server

6.5M-> 3.9M 壓縮比約爲 60%。

UPX + 編譯器選項

同時啓用 UPX 和 -ldflags="-s -w":

➜  binary-size git:(main) ✗ go build -ldflags="-s -w"  -o server main.go && upx --brute server && ls -lh server 
 -rwxr-xr-x  1 hxzhouh  staff   1.4M Jul  2 14:40 server

最後,我們得到的可執行文件大小爲 1.4M,而未經壓縮的文件大小爲 6.5M,節省了大約 80% 的空間。這對於大型應用程序來說是相當可觀的。

How UPX Works

壓縮後的程序與原始程序一樣,無需解壓縮即可正常運行。這種壓縮方法稱爲外殼壓縮,包括兩個部分:

執行時還包括兩個部分:

如果對編譯大小沒有嚴格要求,可以選擇不使用 UPX 壓縮。一般來說,服務器端獨立後臺服務不需要壓縮大小。不過,如果是在 Raspberry Pi 等嵌入式設備上,還是值得一試。

結論

這個帖子 [2] 有很多很有意思的答案:

參考資料

[1]

UPX: https://upx.github.io/

[2]

how-to-reduce-go-compileed-file-size: https://stackoverflow.com/questions/3861634/how-to-reduce-go-compiled-file-size

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/EAFa7DiTkl_AMu--IQ634Q