www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why are binaries/executables so large on Windows?

reply rpgfan3233 <rpgfan3233 gmail.com> writes:
Some thing as simple as:

void main ()
{
}

generates a 75kb executable with dmd 1.018 using the following line:
dmd -O -release test.d

Does anybody know why this happens? The one thing that prevents me from using D
is the large size of the generated files.

Here are the sizes of the files generated by the compiler:
test.obj - 395 bytes
test.map - 2390 bytes
test.exe - 76828 bytes

Is Microsoft's OMF naturally large? Are runtime type checks to blame?

If anybody could help or explain this to me, it would be greatly appreciated.
Jul 20 2007
next sibling parent Tristam MacDonald <swiftcoder gmail.com> writes:
This is primarily because the current setup has the exututabe linked against a
static runtime library. I am not sure about Windows, but on most platforms the
C and C++ runtime libraries are dynamically linked, which makes the executables
a lot smaller.

The test.obj is about the size your executable would be with static linking to
the runtime.

There is no reason why you couldn't compile a dynamic version of the library,
and link to that instead (and in fact, several people on this mailing list have
done it already - use the search)., although this may be somewhat more
complicated on Windows than on Mac/Unix

rpgfan3233 Wrote:
 Some thing as simple as:
 
 void main ()
 {
 }
 
 generates a 75kb executable with dmd 1.018 using the following line:
 dmd -O -release test.d
 
 Does anybody know why this happens? The one thing that prevents me from using
D is the large size of the generated files.
 
 Here are the sizes of the files generated by the compiler:
 test.obj - 395 bytes
 test.map - 2390 bytes
 test.exe - 76828 bytes
 
 Is Microsoft's OMF naturally large? Are runtime type checks to blame?
 
 If anybody could help or explain this to me, it would be greatly appreciated.

Jul 20 2007
prev sibling next sibling parent reply Hoenir <mrmocool gmx.de> writes:
rpgfan3233 schrieb:
 Does anybody know why this happens? The one thing that prevents me from using
D is the large size of the generated files.

extensive applications) You use an executable packer if you want the size to be reduced nevertheless.
Jul 20 2007
parent reply Tristam MacDonald <swiftcoder gmail.com> writes:
But 70k is an impressive overhead for an empty main function... And how will an
executable packer help when most of them are incompatible with DMD?
Hoenir Wrote:
 rpgfan3233 schrieb:
 Does anybody know why this happens? The one thing that prevents me from using
D is the large size of the generated files.

extensive applications) You use an executable packer if you want the size to be reduced nevertheless.

Jul 20 2007
next sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Tristam MacDonald wrote:
 But 70k is an impressive overhead for an empty main function... And how will
an executable packer help when most of them are incompatible with DMD?

UPX works with DMD just fine. I use it with my own code. http://upx.sourceforge.net/ To see how much difference it'd make, I wrote this empty program: module empty; void main () {} With DMD 1.018/Tango/WinXP it compiled to 102,940 bytes (100.5 KB). I ran: upx -9 empty.exe It packed down to 44,032 bytes (43 KB). I consider that a pretty nice improvement. :) -- Chris Nicholson-Sauls
Jul 20 2007
parent Tristam MacDonald <swiftcoder gmail.com> writes:
Having searched the newsgroup, I had only found reports of UPX not working with
DMD produced executables. I guess the bugs have been fixed in one or the other
since the last discussion.

Chris Nicholson-Sauls Wrote:
 Tristam MacDonald wrote:
 But 70k is an impressive overhead for an empty main function... And how will
an executable packer help when most of them are incompatible with DMD?

UPX works with DMD just fine. I use it with my own code. http://upx.sourceforge.net/ To see how much difference it'd make, I wrote this empty program: module empty; void main () {} With DMD 1.018/Tango/WinXP it compiled to 102,940 bytes (100.5 KB). I ran: upx -9 empty.exe It packed down to 44,032 bytes (43 KB). I consider that a pretty nice improvement. :) -- Chris Nicholson-Sauls

Jul 20 2007
prev sibling next sibling parent reply "Stewart Gordon" <smjg_1998 yahoo.com> writes:
"Tristam MacDonald" <swiftcoder gmail.com> wrote in message 
news:f7r3rm$16ig$1 digitalmars.com...
 But 70k is an impressive overhead for an empty main function... And how 
 will an executable packer help when most of them are incompatible with 
 DMD?

The only executable packers I know of work directly with EXEs. So why should they care what compiler was used? Stewart.
Jul 20 2007
parent Gregor Richards <Richards codu.org> writes:
Stewart Gordon wrote:
 "Tristam MacDonald" <swiftcoder gmail.com> wrote in message 
 news:f7r3rm$16ig$1 digitalmars.com...
 But 70k is an impressive overhead for an empty main function... And 
 how will an executable packer help when most of them are incompatible 
 with DMD?

The only executable packers I know of work directly with EXEs. So why should they care what compiler was used? Stewart.

They use ridiculously gross tricks that can cause the environment at entry to be slightly askew. - Gregor Richards
Jul 20 2007
prev sibling parent Hoenir <mrmocool gmx.de> writes:
Tristam MacDonald schrieb:
 But 70k is an impressive overhead for an empty main function... And how will
an executable packer help when most of them are incompatible with DMD?

And 70k is really nothing in these days.
Jul 24 2007
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"rpgfan3233" <rpgfan3233 gmail.com> wrote in message 
news:f7qlnl$goj$1 digitalmars.com...
 generates a 75kb executable with dmd 1.018 using the following line:
 dmd -O -release test.d

 Does anybody know why this happens? The one thing that prevents me from 
 using D is the large size of the generated files.

The one thing? The one, single, motivating factor for you to not use D is because an empty executable is 70KB? Unless you're developing for an embedded system, or competing in the 64k demo competition, there's no need for executables to be very, very small. This 70KB is largely due to the runtime type info which is included (and necessary) for most of the runtime to use. This also includes the garbage collector. This is pretty much a constant overhead. You can think of the size of the EXE as a line ax + b, where b is 70K and x is the amount of user code. Have you tried building a larger program? You'll end up with EXEs very similar in size to those written in other languages.
Jul 20 2007
parent reply "Stewart Gordon" <smjg_1998 yahoo.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:f7r6fp$1ahq$1 digitalmars.com...
<snip>
 This 70KB is largely due to the runtime type info which is included (and 
 necessary) for most of the runtime to use.

Most of the runtime? Why? At the moment we have: - AAs - sorting - variadic functions (Is RTTI basically just the TypeInfo classes in D?) Of course, garbage collection could also use RTTI, but does the current GC implementation use it? Moreover, ISTM that even if the runtime does need RTTI, I'd think the average program wouldn't need it for every single type in the language, the program and any library it uses. There ought to be a way to optimise by linking in the RTTI for only those types where it's actually needed.
 This also includes the garbage collector.

What does - the 70KB, RTTI or "most of the runtime"? Stewart.
Jul 24 2007
parent Sean Kelly <sean f4.ca> writes:
Stewart Gordon wrote:
 "Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
 news:f7r6fp$1ahq$1 digitalmars.com...
 <snip>
 This 70KB is largely due to the runtime type info which is included 
 (and necessary) for most of the runtime to use.

Most of the runtime? Why? At the moment we have: - AAs - sorting - variadic functions (Is RTTI basically just the TypeInfo classes in D?)

Yes.
 Of course, garbage collection could also use RTTI, but does the current 
 GC implementation use it?

In a way. The runtime pulls certain information from TypeInfo to tell the GC whether blocks it allocates contain pointers.
 Moreover, ISTM that even if the runtime does need RTTI, I'd think the 
 average program wouldn't need it for every single type in the language, 
 the program and any library it uses.  There ought to be a way to 
 optimise by linking in the RTTI for only those types where it's actually 
 needed.

I think the problem here is file-level linking. To get around this with the current linker you'd need to generate a separate file for every TypeInfo used by the app, and then only link the ones that are actually used. Section-level linking would be much easier to accomplish.
 This also includes the garbage collector.

What does - the 70KB, RTTI or "most of the runtime"?

For a "hello world" application, the 70k is mostly runtime code rather than TypeInfo. The runtime itself doesn't contain many objects, so it doesn't generate a lot of TypeInfo all by itself. Sean
Jul 24 2007