-
1 Attachment(s)
overgrown .exe files
I wrote this little program to help explain how mergesort works and noticed that if i compile it with Dev-C++ the executable is less than 77K, but compiled with the free Borland CPP Builder 5.5 the executable is over 154K -- literally twice as big.
Does this Borland compiler always waste so much space?
Why?
How should I have written this differently to let Borland compile it without creating such a bloated file?
(I already tried "using std::cin; using std::cout; using std::endl;" instead of "using namespace std;" but that didn't save any space at all -- with either compiler.)
-
I'm not sure why this is but just to let you know, on my GCC compiler, it took up 411kb and with MSVC++ it took up 524kb.
-
Using MSVC++ 6.0 (Sp 4 or 5, can't remember):
Code:
Release Mode Debug Mode
Default Options 112 Kb 525 Kb
C/C++ Options (minimize size) 96 Kb NA
As you can see, compiling under release/debug mode changes the size as does going into Project->Settings->C/C++ Tab->Optimizations->Minimize Size. That's with MSVC, chances are that your compiler also has options/tricks to reduce size of an executable.
-
The bulk of the space is taken up by
- whether its a debug or a release build. Debug information takes up a lot of space, and release builds typically have minimal (or zero) debug information.
- whether libraries are statically or dynamically linked. static libs take up space, whereas dynamic libs contain just stubs to load the actual library at run-time.
- how well written the libraries are - do you get just the symbols you need or do you get a lot of 'useless' baggage as well.
-
I really don't know why people care so much about the sizes of their EXEs. If its 400 KB --> who cares? Its probably just loaded with all the OS stuff needed to make your program work. Just take a look at any game, it loads maybe up to 90 megabytes into RAM. Your little console application will load maybe 400 KB. When most computers nowadays have 256 MB RAM and up, who cares about an extra 200 KB, especially when your program is graphical.
The only places where size matters is microcontroller programming and other small devices.
-
Because if you don't worry about size, it get's hairy when you create a large application.
Comparing games to other applications is not fair, being that games use massive ammounts of recources. And yes, we game designers to take the size of our .exe into considerations, and try to minimize it, along with all other files we use.
-
Hmmm... I hadn't even tried it with MSVC but yes, I get the same 112/525 results with that one. I didn't even realize before now that there were two different build modes in MSVC. I've only used the build mode, so thanks for pointing that out.
I read some of the Borland documentation (imagine that :D ) & found that there is a -O1 switch that compiles for "smallest possible code", but compiling with that gave exactly the same size (154,624) code.
So apparently it's not debugging info that's loading it up. And, Salem, do you really think that Dev-C++ is compiling this little program with dynamic linking? All 3 exe's run equally well on a computer that has no compilers installed (or could it be finding dlls someplace in Windows' directory?).
I guess it comes down to Salem's comment about 'excess baggage', which gets back to my original question. Is there a way to #include a subset of <iostream> to accomodate just cin and cout to save space?
Oh, and Speedy5: you answered your own question in your last sentence. True, for this particular program it doesn't really matter much, but for AI programs for small robots with limited memory size definitely does matter. And anyway, to paraphrase a well-known saying, a billion here, a billion there, & pretty soon ...
-
Anyway, to make a long story short, is this Borland compiler generally considered to be less efficient spacewise than other compilers?
-
I think you need to figure out all your compiler options, and what additional tools there are available.
For example, if you're that worried by the size, then consider using an exe packing tool like UPX.
Besides, once you've got the standard library linked into the executable, you can use if freely without increasing the size of your executable.
Your exe might be a bloated 500KB with your simple "hello world", but the exe could be still only 600KB with your 10K line significant application and you'll be thinking you're getting a good deal on the size front.
GCC derived compilers (Dev-C++ is one of them) should have these facilities which are available on pretty much any Unix/Linux based system.
These are some size stats for compiling your program
Code:
# compile only
$ g++ T_mergesort.cpp
$ ls -l a.out
-rwxrwxr-x 16870 Apr 8 22:02 a.out
# compile with debug
$ g++ -g T_mergesort.cpp
$ ls -l a.out
-rwxrwxr-x 125638 Apr 8 22:02 a.out
# size tells you how big the real code is
# strip removes all debug and symbol table information
$ size a.out
text data bss dec hex filename
4531 856 300 5687 1637 a.out
$ strip a.out
$ size a.out
text data bss dec hex filename
4531 856 300 5687 1637 a.out
$ ls -l a.out
-rwxrwxr-x 7240 Apr 8 22:03 a.out
# well over 100K of debug information removed from the executable
# static linking of the run-time library
# this adds a LOT of stuff to the executable
$ g++ -static T_mergesort.cpp
$ ls -l a.out
-rwxrwxr-x 3566198 Apr 8 22:06 a.out
$ size a.out
text data bss dec hex filename
700367 74565 25536 800468 c36d4 a.out
# size contribution of just your own code
$ g++ -c T_mergesort.cpp
$ ls -l T_mergesort.o
-rw-rw-r-- 6460 Apr 8 22:23 T_mergesort.o
$ size T_mergesort.o
text data bss dec hex filename
2735 528 8 3271 cc7 T_mergesort.o
As you can see, there is a huge range of possible sizes depending on exactly how you compile and link the same piece of code.
The only real way to compare one compiler against another (or different options for a compiler) is to compare what results you get with the last command shown above (the -c example).
-
Fascinating. Thanks Salem.
I compiled the same source code with g++ on my school Solaris system & a.out was 13660 bytes, and then strip took it down to 3531 bytes.
I tried it with g++ on my linux system & it came in at 3531 bytes immediately.
So far, Dev-C++ comes up with the smallest .exe of the Windows-version compilers; a distant 75,776 bytes.
Followed by the "release" version under MSVC 6.0 at 114,688 bytes, and then the Borland 5.5 at 154,624 bytes.
These are all *supposedly* without any debug code. I don't see anything equivalent to strip in any of the Windows compilers' bin directories.
So why are the Windows versions so drastically bigger than the Unix/Linux versions? Are the latter depending on the machine having code libraries to be linked at runtime, while the former are "stand-alone"?
-
I don't know if there is any equivallent in Borland, but in VC++ you can do this. It makes most of my console apps less than 20k.
-
Fascinating, Tybalt.
That trick reduced the VisualC++ exe down from 112K to 6656 bytes.
Would you (or anyone) care to explain what it actually did?
-
> So why are the Windows versions so drastically bigger than the Unix/Linux versions?
Look at what -static did to the size of my linux executable
VC++ can dynamically link with libraries, you just have to tweak the right option
I don't have it to hand at the moment to find out though.
> Would you (or anyone) care to explain what it actually did?
VC++ can edit files in binary mode. Load the "before and after" copies of the executable.
You'll still see a lot of symbolic information in the original
-
>> VC++ can dynamically link with libraries, you just have to
>> tweak the right option
>> I don't have it to hand at the moment to find out though.
This is part of Tybalt's "trick". Under project/settings/C-C++/code generation/use run-time library there is an entry for "Multithreaded dll". Applying this reduced the size of the .exe to 16384 bytes.
But he also does: under project/settings/link/Project Options add an entry "/align:16384" (this number has nothing to do with the 16384 I mentioned above; purely coincidental). After adding that switch and re-compiling & building, the .exe is now only 6656 bytes.
Do you know what that /align switch is doing?
---------------------------------------------------------------------------
I did some more googling & found that there is a command-line switch for the Borland compiler, -tWCR that enables dynamic linking. Using that brings the Borland-compiled .exe down to 9,216 bytes. But now it only runs on a computer that has Borland's runtime library installed.
On the other hand, the tiny VisualC++ .exe compiled with Tybald's approach seems to run on any Windows PC. Is it using a runtime library that is actually a part of Windows itself?
-----------------------------------------------------------------------------
>> VC++ can edit files in binary mode. Load the "before and
>> after" copies of the executable.
>> You'll still see a lot of symbolic information in the original
I looked at them, but I'm not sure what I'm supposed to see. I see that there's a lot more code in the original, but we already knew that. And I have no idea what the code means.