golang/go

cmd/compile: compress static initialization data?

gopherbot opened this issue · 9 comments

by Tyr.Chen:

This code http://play.golang.org/p/e6L16l7i7S will generate 81M executable when doing
"go build". 

$ ls -l
-rwxr-xr-x  1 tchen  522017917  81533376 Dec 20 08:22 test

While changing the code using global variable fixed the issue.
http://play.golang.org/p/pqh9XO_m2J

$ls -l
-rwxr-xr-x  1 tchen  522017917  1534384 Dec 20 08:26 test

See further discussion on
http://stackoverflow.com/questions/20671535/why-this-code-generate-very-big-executable-in-go-around-81m.

Comment 1 by Tyr.Chen:

I'm using osx 10.8.2, go version is 1.1.2.
➜  go  go version
go version go1.1.2 darwin/amd64

Comment 2:

Also occurs on trunk (so assuming 1.2 as well)

Comment 3:

What were you expecting? This seems obvious to me. The compiler
has to store the composite literal data somewhere in the binary.
If you want the zero value, use the zero value:
 func (self *BigData) Clear() {
-   *self = BigData{}
+   var zero BigData
+   *self = zero
 }
Also, you should realize that you're making a bunch of 80MB copies.
#WorkingAsIntended

Comment 4:

I think this is bug. I think the compiler should optimize *self = BigData{}
to a simple memclr.

Comment 5 by Tyr.Chen:

Agree that compiler should optimize this use case. I saw bunch of code examples like "x
:= Y{}".

Comment 6:

on 2nd thought, the compiler probably should consider some simple data compression
technique here.
for example, *self = BigData{1, 2, 3} should use no more than 3 uint64s.

Labels changed: added release-none, repo-main.

Status changed to LongTerm.

Comment 7:

Still present on tip:
go version devel +931cc1aeb3be Wed Jan 22 23:30:52 2014 +0100 linux/arm
In this program: http://play.golang.org/p/EikUFnNvqj a big array (not a slice) of a
struct is created and accessed with range using the index or the value. It seems that if
the struct contains a string (even if not used) AND the struct is accessed using the
value, compilation uses a lot of memory and the program produced is really big or even
fails to compile. 
The program in playground uses about 100 MB of RAM to compile and the binary is 54 MB.
Removing the string (or replacing it by an array of ints, for example) or removing the
second for range loop, will solve the problem.

For reference, the binary is just 4.2MB now with 1.9.2.

Ok, I'm going to close this then.