我们都知道,Go有一个很重要的特点,那就是它的编译速度非常快,编译速度是Go语言设计的时候就重点考虑[1]的问题. 但是您有没有观察过Go语言编译后的二进制可执行文件的大小?我们先用一个简单的http server 的例子来看看。
import (
"fmt"
"net/http"
)
funcmain() {
// 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 hxzhouh staff 6.5M Jul 2 14:20 server
Go语言的编译器会对二进制文件的大小进行裁剪,如果您对这部分的内容感兴趣,请阅读我的另外一篇文章How Does the Go Compiler Reduce Binary File Size?[2]
现在我们来尝试优化一下server
的大小。
Go 编译器默认编译出来的程序会带有符号表和调试信息,一般来说 release 版本可以去除调试信息以减小二进制体积。
➜ 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[3] 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.
在Mac 上可以通过brew 安装upx
brew install upx
upx 有很多参数,最重要的则是压缩率,1-9
,1
代表最低压缩率,9
代表最高压缩率。
接下来,我们看一下,如果只使用 upx 压缩,二进制的体积可以减小多少呢。
➜ binary-size git:(main) ✗ go build -o server main.go && upx -9 server && ls -lh server
-rwxr-xr-x 1 hxzhouh staff 3.9M Jul 2 14:38 server
压缩比例达到了 60%
同时开启 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%的空间,对于大型应用,还是挺可观的。
upx 压缩后的程序和压缩前的程序一样,无需解压仍然能够正常地运行,这种压缩方法称之为带壳压缩,压缩包含两个部分:
执行时,也包含两个部分:
https://stackoverflow.com/questions/3861634/how-to-reduce-go-compiled-file-size[4] 这帖子里面有很多有意思的答案,
println
来替代 fmt.println
就能避免引入fmt包,进一步缩小体积。[1]重点考虑: https://go.dev/doc/faq#creating_a_new_language
[2]How Does the Go Compiler Reduce Binary File Size?: https://levelup.gitconnected.com/smart-go-compiler-slimming-bf6a03a7a5dc
[3]UPX: https://upx.github.io/
[4]https://stackoverflow.com/questions/3861634/how-to-reduce-go-compiled-file-size