In this post I will talk about the file size of programs written
with Go. The compiled programs were very large and it was
interesting to see what gccgo brought into the issue.
Shrink: This program loads two files with json encoded data in it. With the data in them it builds a list of files and for each file it will call two external programs to shrink the file size.
73 lines of code.
Serve: This program builds a list of files and serves them via http. To build the list it has to read directories and load and parse json files. The files include a HTML 5 app, a list of workload history files and the files referenced in the workload history files.
155 line of code.
Files size:
Program |
Size in Bytes |
Shrink |
1 791 430 (about 1.8 MB) |
Serve |
3 991 224 (about 3.9 MB) |
Cshrink |
41 486 |
Cserve |
80 345 |
Update: Json and http server are part of Go runtime. The latter is only used in Serve. That will explaini the huge size difference for the static version.
The first two version were compiled into static programs using the go tool, while the second two were compiled with gccgo and have references to libraries. Using ldd on them gave me this:
linux-vdso.so.1 => (0x00007fffb94c0000)
libgo.so.0 => /usr/lib/x86_64-linux-gnu/libgo.so.0 (0x00007facc4578000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007facc4362000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007facc3fa2000)
/lib64/ld-linux-x86-64.so.2 (0x00007facc7272000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007facc3d85000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007facc3a89000)
Note: libgo alone has about 12MB making the smaller gccgo version in fact fatter.
To put this in a better context I've created three hello world programs. Two in pure C and one in C++.
- hello: pure hello world program in C
- hello2: hello with a for loop that prints the number 0 to 9
and calls the ls program.
- hellopp: Same function like hello but implemented in pure C++.
File size again:
Program | Size in Bytes |
hello |
8 706 |
hello2 |
8 811 |
hellopp |
9 325 |
Thats very interesting. The C++ version is even larger than the
extended C version but they all are about a fifth of the simple
Shrink program. It gets more interesting when doing an ldd.
ldd on C:
linux-vdso.so.1 =>
(0x00007ffff8bff000)
libc.so.6 =>
/lib/x86_64-linux-gnu/libc.so.6 (0x00007f10322a2000)
/lib64/ld-linux-x86-64.so.2
(0x00007f1032685000)
ldd on C++:
linux-vdso.so.1 =>
(0x00007fff809ff000)
libstdc++.so.6 =>
/usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7de2f33000)
libc.so.6 =>
/lib/x86_64-linux-gnu/libc.so.6 (0x00007f7de2b74000)
libm.so.6 =>
/lib/x86_64-linux-gnu/libm.so.6 (0x00007f7de2877000)
/lib64/ld-linux-x86-64.so.2
(0x00007f7de325a000)
libgcc_s.so.1 =>
/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7de2661000)
Putting the data above together
The static binaries of gc are still ver large and even gccgo
fails to get into regions of C/C++. Looking on the dependencies of
the gccgo tells me that only libgo.so and lipthread.so are missing
in the C++ version. I suppose libpthread would get into in when I
needed threading. So compared to C++ I have only the libgo.so as
an additional dependency.
Could I use go to build the userspace of a while distrubtion.
With the static version definitely not. With the gccgo version
maby. At this post
(German) someone complains that a 500K binary could be done in 10K
when they had used C instead of C++ with Boost. So the overhead of
gccgo may be acceptable and 12MB per installation is nothing.
Is gc (static compiler) useless? No. I have seen organizations
that provide a full Virtal Machine with an Java application server
and several GB of RAM for each single application in order to
ensure that the applications don't interfere. Compared to that the
Go programs are ultra slim. Besides such extremes imagine you have
written this cool php application and want to give it to a friend
for testing. He needs to install apach and php to test it. With go
you put some MB on dropbox and he loads it.
As seen gccgo and gc have both their strengths and you need to
choose situationally one of them.