How to reduce compiled file size?

前端 未结 12 708
野性不改
野性不改 2020-11-28 20:59

Lets compare c and go: Hello_world.c :

#include
int main(){
    printf(\"Hello world!\");
}

Hello_world.go:

         


        
相关标签:
12条回答
  • 2020-11-28 21:19

    By default gcc links dynamically and go - statically.

    But if you link you C code statically, you might get a binary with a bigger size.

    In my case:

    • go x64 (1.10.3) - generated binary with size 1214208 byte
    • gcc x64 (6.2.0) - generated binary with size 1421312 byte

    both binaries are statically linked and without debug_info.

    go build -ldflags="-s -w" -o test-go test.go
    gcc -static -s -o test-c test.c
    
    0 讨论(0)
  • 2020-11-28 21:20

    Is it a problem that the file is larger? I don't know Go but I would assume that it statically links some runtime lib which is not the case for the C program. But probably that is nothing to worry about as soon as your program gets larger.

    As described here, statically linking the Go runtime is the default. That page also tells you how to set up for dynamic linking.

    0 讨论(0)
  • 2020-11-28 21:21

    If you are using a Unix-based system (e.g. Linux or Mac OSX) you could try removing the debugging information included in the executable by building it with the -w flag:

    go build -ldflags "-w" prog.go
    

    The file sizes are reduced dramatically.

    For more details visit the GDB's page: http://golang.org/doc/gdb

    0 讨论(0)
  • 2020-11-28 21:25

    The binary contains by default the garbage collector, the schedulding system that manage the go routines, and all the libraries you import.

    The result is a minimal size of about 1 Mb.

    0 讨论(0)
  • 2020-11-28 21:29

    More compact hello-world example:

    package main
    
    func main() {
      print("Hello world!")
    }
    

    We are skiped large fmt package and noticeably reduced binary:

      $ go build hello.go
      $ ls -lh hello
      ... 259K ... hello2
      $ strip hello
      $ ls -lh hello
      ... 162K ... hello2
    

    Not so compact as C, but though measured in K not M :) Ok, it is not general way just shows some ways to optimize a size: use strip and try to use minimum packages. Anyway Go is not language for making tiny sized binaries.

    0 讨论(0)
  • 2020-11-28 21:29

    2018 answer for the next Go 1.11, as tweeted by Brad Fitzpatrick (mid-June 2018):

    As of a few minutes ago, DWARF sections in #golang ELF binaries are now compressed, so at tip binaries are now smaller than Go 1.10, even with all the extra debug stuff at tip.

    Cf. Golang issue 11799:

    Compressing our debug info might offer a significant, cheap file size win.

    See more in commit 594eae5

    cmd/link: compress DWARF sections in ELF binaries

    The trickiest part of this is that the binary layout code (blk, elfshbits, and various other things) assumes a constant offset between symbols' and sections' file locations and their virtual addresses.

    Compression, of course, breaks this constant offset.
    But we need to assign virtual addresses to everything before compression in order to resolve relocations before compression.

    As a result, compression needs to re-compute the "address" of the DWARF sections and symbols based on their compressed size.
    Luckily, these are at the end of the file, so this doesn't perturb any other sections or symbols. (And there is, of course, a surprising amount of code that assumes the DWARF segment comes last, so what's one more place?)

    name        old exe-bytes   new exe-bytes   delta
    HelloSize      1.60MB ± 0%     1.05MB ± 0%  -34.39%  (p=0.000 n=30+30)
    CmdGoSize      16.5MB ± 0%     11.3MB ± 0%  -31.76%  (p=0.000 n=30+30)
    [Geo mean]     5.14MB          3.44MB       -33.08%
    

    Rob Pike mentions:

    That only helps on machines that use ELF.
    Binaries are still too big, and growing.

    Brad replied:

    At least it's something. Was about to be much worse.
    Stopped the bleeding for one release.

    Reasons: Debug info, but also register map for the GC to let any instruction be a savepoint.

    0 讨论(0)
提交回复
热议问题