Lets compare c and go: Hello_world.c :
#include
int main(){
printf(\"Hello world!\");
}
Hello_world.go:
You may take a look at my small research on this subject: https://github.com/xaionaro/documentation/blob/master/golang/reduce-binary-size.md
It shows step-by-step how to reduce a 2MiB hello-world static-binary sample to 15KiB static-binary or to 10KiB dynamic-binary. Of course there's a lot of limitations.
The 2016 answer:
1. Use Go 1.7
2. Compile with go build -ldflags "-s -w"
➜ ls -lh hello
-rwxr-xr-x 1 oneofone oneofone 976K May 26 20:49 hello*
3. Then use upx
, goupx
is no longer needed since 1.6.
➜ ls -lh hello
-rwxr-xr-x 1 oneofone oneofone 367K May 26 20:49 hello*
create a file named main.go
,
let's try with simple hello world program.
package main
import "fmt"
func main(){
fmt.Println("Hello World!")
}
I use go version 1.9.1
$ go version
go version go1.9.1 linux/amd64
Compile with standard go build
command.
$ go build main.go
$ ls -lh
-rwxr-xr-x-x 1 nil nil 1.8M Oct 27 07:47 main
Let's compile once again with go build
but with ldflags
as suggested above,
$ go build -ldflags "-s -w" main.go
$ ls -lh
-rwxr-xr-x-x 1 nil nil 1.2M Oct 27 08:15 main
File size is reduced by 30%.
Now, lets use gccgo
,
$ go version
go version go1.8.1 gccgo (GCC) 7.2.0 linux/amd64
Building go with gccgo
,
$ go build main.go
$ ls -lh
-rwxr-xr-x 1 nil nil 34K Oct 27 12:18 main
Binary size is reduced by almost 100%.
Let's once again try building our main.go
with gccgo
but with build flags,
$ go build -gccgoflags "-s -w" main.go
-rwxr-xr-x 1 nil nil 23K Oct 27 13:02 main
Warning:
As gccgo
binaries were dynamically linked.
If you have a binary which is very big in size, your binary when compiled with gccgo will not be decreased by 100%, but it will be reduced in size by considerable amount.
Compared to gc, gccgo is slower to compile code but supports more powerful optimizations, so a CPU-bound program built by gccgo will usually run faster. All the optimizations implemented in GCC over the years are available, including inlining, loop optimizations, vectorization, instruction scheduling, and more. While it does not always produce better code, in some cases programs compiled with gccgo can run 30% faster.
The GCC 7 releases are expected to include a complete implementation of the Go 1.8 user libraries. As with earlier releases, the Go 1.8 runtime is not fully merged, but that should not be visible to Go programs.
Pros:
Cons
go
.You can see over here and here.
You should get goupx, it will "fix" Golang ELF executables to work with upx
. I've already got around 78% file size shrink in some cases ~16MB >> ~3MB
.
Compression ratio usually tends to 25%, so it's worth a try:
$ go get github.com/pwaller/goupx
$ go build -o filename
$ goupx filename
>>
2014/12/25 10:10:54 File fixed!
File size Ratio Format Name
-------------------- ------ ----------- -----------
16271132 -> 3647116 22.41% linux/ElfAMD filename
Packed 1 file.
EXTRA: -s
flag (strip) can shrink bin file even more goupx -s filename
Go binaries are large because they are statically linked (except for library bindings using cgo). Try statically linking a C program and you'll see it grow to a comparable size.
If this is really a problem for you (which I have a hard time believing), you can compile with gccgo and dynamically link.
From Go 1.8 you can also use the new plugin system to split up your binary into something that resembles shared libraries. For this release it only works on Linux, but other platforms will probably be supported in the future.
https://tip.golang.org/pkg/plugin/