1. 47
  1.  

  2. 5

    Been waiting for this release, very nice! Hope binary sizes keep shrinking.

    1. 2

      Provided they don’t become absurd, why do you care about binary sizes?

      1. 3

        I’ve got some pretty slow internet - this morning I was downloading terraform 0.13 at ~70kb/s, haha. Granted, it’s a particularly large example.

        Go hello world is ~10 MB. I understand there’s a lot of runtime packed in there (or something else? Go binaries compress particularly well, so there’s not a lot of entropy somewhere), but for some perspective I’ll beat the dead horse and say statically including musl libc weighs ~1 MB at most. So, it would be pretty cool to have like, 5 MB go hello world. I’d guess the go linker could be more smart, I never actually bothered to look at what’s taking up space.

        In the end, it’s not really an issue for me personally. Definitely being idealistic here. I’d guess the engineering effort involved would just not be worth it, at least not to Google.

        1. 1

          10MB seemed outrageous to me, so I checked. Using

          package main
          import "fmt"
          func main() { fmt.Println("Hello, world!") }
          

          the binary output is 2MB for both 1.14 and 1.15. So I guess it’s pretty cool?

          Also, since this release does shrink binary sizes, it shows that people are spending the engineering effort involved to shrink them.

          1. 2

            Ah sorry, I didn’t actually bother to verify my poor memory there. Thanks.

      2. 1

        Yes. I wish there was something like Go that could produce relly tiny ELF files.

        1. 3

          Does tinygo help?

          1. 2

            Have you looked at upx? Shrinks my Go binary by 50%.

            -rwxr-xr-x   1 mikeperham  staff   5910544 Aug 12 12:32 faktory
            -rwxr-xr-x   1 mikeperham  staff  11506756 Aug 12 12:32 faktory-big
            

            https://upx.github.io

            1. 3

              It helps, but I’m thinking that an “hello world” ELF file making one system call to print the message and one to exit the program should take less than two kilobytes, not close to two megabytes (or more).

              What is the Go compiler storing in a “hello world” executable to make it that large, and more importantly: why are unused bytes not automatically removed?

              1. 3

                Compared to C, there’s the addition of a garbage collector and a unicode database, at minimum.

                1. 1

                  But there already is a Unicode database in your system?

                  1. 2

                    Can you provide a list of all of the locations for all of the unicode databases on every one of these systems: https://github.com/golang/go/blob/master/src/go/build/syslist.go#L10

                    Additionally, provide the methods of interfacing with them, what their differences are, and what their commonalities are? Please be sure to do that for every version of Go for the last 10 years.

                    Too much work? I agree.

                    1. 1

                      Not one designed for fast in-memory access using, say, a paged array data structure. You really don’t want to parse and convert the UnicodeData.txt files provided by the unicode consortium into a reasonable query structure every time you start a binary that does text processing.

                  2. 1

                    You want Rust? Go always includes a managed runtime for GC, et al.

                    1. 1

                      No, I get that Go and Rust aims for different things, but I don’t understand why the runtime is included if it’s not being used.

                      1. 2

                        Because for any non-trivial program, the runtime will be included. Why care about optimizing binary size of a program that is useless?

                        1. 1

                          Embedded platforms often require small sizes. And I would love to use Go for writing a 4k demoscene demo, if it had been possible.

                          Regardless of the above, why include unused bytes in the first place?

                          1. 2

                            Because there’s engineering effort involved both in initial implementation and long term maintenance. Approximately zero programs would benefit from that engineering effort.

                            1. 1

                              I agree that there is effort required to implement it in the first place, but fewer bytes emitted usually results in a lower maintenance cost. That’s my intuition, at least.

                              All it takes is one dedicated developer that decides to send a pull request.

                              1. 2

                                I think you are misestimating multiple things.

                                1. The set of useful programs that do not use the runtime. You cannot allocate, use goroutines, use channels, use maps, use interfaces, or large portions of the reflect library, just to get started.
                                2. The effort involved to make the runtime removed from the small programs that don’t use it. The dead code elimination required is a non-trivial problem due to things like package initialization, generating tracebacks on crashes, etc.
                                3. The ongoing effort involved in maintaining that code. It would have to remain under test, work on all of the environments that support it, etc. That the compiler outputs less bytes in some specialized programs that can basically only add numbers does not imply that there would be less things to maintain going forward.

                                There is no calculus that makes this a useful optimization. The developers consistently have been putting in large efforts (like rewriting the linker, for example) to get even marginal (1-5%) reductions in binary size. Not every idea is a good one.

                    2. 1

                      should take less than two kilobytes

                      Compiled a simple “hello world” in both C and Go to static binaries and stripped them.

                      -rwxr-xr-x 1 rjp rjp 715912 Aug 14 08:42 hw-c
                      -rw-r--r-- 1 rjp rjp     97 Aug 14 08:41 hw.c
                      -rwxr-xr-x 1 rjp rjp 849976 Aug 14 08:42 hw-go
                      -rw-r--r-- 1 rjp rjp     52 Aug 14 08:41 hw.go
                      

                      This is GCC 10.1.0, Go 1.14.6 on Linux 5.7.5-arch1-1, x86_64.

                      If I upx them, I get

                      -rwxr-xr-x 1 rjp rjp 283608 Aug 14 08:42 hw-c
                      -rwxr-xr-x 1 rjp rjp 346748 Aug 14 08:42 hw-go
                      
                      1. 1

                        Yes, I dont get why those has to be that large either. Very few assembly instructions are needed.