Thread overview
Huge output size for simple programs
Sep 11, 2015
NX
Sep 11, 2015
Daniel N
Sep 11, 2015
John Colvin
Sep 11, 2015
Jonathan M Davis
Sep 11, 2015
Johannes Pfau
Sep 11, 2015
Adam D. Ruppe
Sep 11, 2015
NX
Sep 11, 2015
Adam D. Ruppe
September 11, 2015
I compile a simple hello world program in C and the results:

hello_world.o -> 1.5 KB
hello_world (linux executable) -> 8.5 KB


Then I compile a simple hello world program in D (using DMD) and the results:

hello_world.o -> 9.3 KB
hello_world (linux executable) -> 575.9 KB


Then I compile a simple hello world program in D (using GDC) and the results:

hello_world.o -> 24.6 KB
hello_world (linux executable) -> 13 MB !!!

What's the reason for that? What makes D applications so much bloated?
Is this because whole GC implementation code is injected into executable or maybe libphobos.a being statically linked or is this because TypeInfo* ModuleInfo* stuff?
September 11, 2015
On Friday, 11 September 2015 at 11:15:33 UTC, NX wrote:
> I compile a simple hello world program in C and the results:
>
> hello_world.o -> 1.5 KB
> hello_world (linux executable) -> 8.5 KB
>
>

If you care about binary sizes, use ldc2:
ldc 225544 bytes (stripped + writeln)
ldc 175736 bytes (stripped + puts)

with tricks you can get lower, but that's out of the box...
September 11, 2015
On Friday, 11 September 2015 at 11:15:33 UTC, NX wrote:
> I compile a simple hello world program in C and the results:
>
> hello_world.o -> 1.5 KB
> hello_world (linux executable) -> 8.5 KB
>
>
> Then I compile a simple hello world program in D (using DMD) and the results:
>
> hello_world.o -> 9.3 KB
> hello_world (linux executable) -> 575.9 KB
>
>
> Then I compile a simple hello world program in D (using GDC) and the results:
>
> hello_world.o -> 24.6 KB
> hello_world (linux executable) -> 13 MB !!!
>
> What's the reason for that? What makes D applications so much bloated?
> Is this because whole GC implementation code is injected into executable or maybe libphobos.a being statically linked or is this because TypeInfo* ModuleInfo* stuff?

static linking is the really big thing here.
September 11, 2015
On Friday, September 11, 2015 11:15:31 NX via Digitalmars-d-learn wrote:
> I compile a simple hello world program in C and the results:
>
> hello_world.o -> 1.5 KB
> hello_world (linux executable) -> 8.5 KB
>
>
> Then I compile a simple hello world program in D (using DMD) and
> the results:
>
> hello_world.o -> 9.3 KB
> hello_world (linux executable) -> 575.9 KB
>
>
> Then I compile a simple hello world program in D (using GDC) and
> the results:
>
> hello_world.o -> 24.6 KB
> hello_world (linux executable) -> 13 MB !!!
>
> What's the reason for that? What makes D applications so much
> bloated?
> Is this because whole GC implementation code is injected into
> executable or maybe libphobos.a being statically linked or is
> this because TypeInfo* ModuleInfo* stuff?

It's primarily because the d runtime and standard library are statically linked, whereas the C runtime and standard library are dynamically linked. Some of the stuff related to TypeInfo and other D-specific features does make it worse than it would be otherwise, but fundamentally, if you're statically linking in the D runtime and standard library, you're always going to get larger programs than when you dynamically link. However, a lot of that won't increase in size as a program's source code increases in size, because the runtime and standard library don't increase in size just because you have more code. I expect that there will be improvements to the size of D binaries in the future though, since there is some desire among the compiler devs to figure out how to reduce it, and you can use libphobos.so if you'd like. It's just that its ABI changes from release to release, so your D programs risk breaking every time you upgrade and thus likely will have to be rebuilt, whereas you wouldn't have the same problem with libphobos.a, since in that case, it all ends up in the executable.

Now, as to why the gdc binary is so large, I don't know. My guess is that it has something to do with the debug symbols. You could try building with -g or -gc to see how that affects the dmd-generated binary.

Regardless, this is the sort of thing that looks really bad with hello world, because your code is really small, and the D runtime and standard library dwarf it, whereas if you have a much larger program, the difference between D and C/C++ is likely to be a lot less noticeable.

- Jonathan M Davis

September 11, 2015
On Friday, 11 September 2015 at 11:15:33 UTC, NX wrote:
> hello_world (linux executable) -> 13 MB !!!

Try running `strip yourexecutable` on all compilers, but on gdc it should make the biggest difference. It brings debugging info and exported symbols.

> Is this because whole GC implementation code is injected into executable or maybe libphobos.a being statically linked or is this because TypeInfo* ModuleInfo* stuff?

Static linking is a couple hundred kilobytes, some of the library being intertwined is a couple hundred more.

C's stdlib is also large, but since it comes with the operating system preinstalled, you don't think about it much. Ditto times twenty for Java, .net, C++, dynamic languages, etc.

Just D's isn't preinstalled so it carries what it needs with the executable for broadest compatibility. You could dynamically link if you like (`-defaultlib=libphobos2.so` on dmd linux) though then to share the application, you've gotta share that multi-megabyte .so as well as the executable.... and deal with dependency management, so it really makes it worse.

And if you aren't distributing it, meh, what's 400 kb on your own hard drive?
September 11, 2015
On Friday, 11 September 2015 at 13:45:03 UTC, Adam D. Ruppe wrote:
> Just D's isn't preinstalled so it carries what it needs with the executable for broadest compatibility. You could dynamically link if you like (`-defaultlib=libphobos2.so` on dmd linux)

So I did some testing:

# dmd -defaultlib=libphobos2.so "app.d"
Source:
void main()
{
	main();
}
Result:
app.o -> 5.3 KB
app (exe) -> 9.4 KB


# dmd -defaultlib=libphobos2.so "app.d"
Source:
import std.stdio, std.conv, core.stdc.stdlib, std.typecons, std.parallelism;
void main()
{
	main();
}
Result:
app.o -> 6 KB
app (exe) -> 13.7 KB


Just because I imported some stuff from a dynamically linked library makes output weirdly big. Try it yourself, change the number of imported modules and output size will significantly change.

One question: Why?
September 11, 2015
On Friday, 11 September 2015 at 14:30:00 UTC, NX wrote:
> One question: Why?

use the map viewer to get more info:

http://thecybershadow.net/d/mapview/

use dmd -map to create the file it wants
September 11, 2015
Am Fri, 11 Sep 2015 05:36:27 -0700
schrieb Jonathan M Davis via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com>:

> Now, as to why the gdc binary is so large, I don't know. My guess is that it has something to do with the debug symbols. You could try building with -g or -gc to see how that affects the dmd-generated binary.

The libphobos shipped with the GDC binaries or with a self-compiled GDC does contain debug information (default GCC policy IIRC?). That combined with static linking leads to huge executables. A simple 'strip' command reduces the executable size.