views:

215

answers:

8

I've inherited a fairly large C++ project in VS2005 which compiles to a DLL of about 5MB. I'd like to cut down the size of the library so it loads faster over the network for clients who use it from a slow network share.

I know how to do this by analyzing the code, includes, and project settings, but I'm wondering if there are any tools available which could make it easier to pinpoint what parts of the code are consuming the most space. Is there any way to generate a "profile" of the DLL layout? A report of what is consuming space in the library image and how much?

+3  A: 

While i don't know about any binary size profilers, you could alternatively look for what object files (.obj) are the biggest - that gives you at least an idea of where your problematic spots are.
Of course this requires a sufficiently modularized project.

Georg Fritzsche
This is a good suggestion. The problem is that they are all about the same size. There are about 30 modules and the object code files are all around 800kb. So it seems that the linker is intelligently removing some overlap but I'd like to get some insight into the composition of what remains.
PeterAllenWebb
I can imagine that such size profiling should be possible with debug information generated - but sadly i haven't heard of any tool for that yet.
Georg Fritzsche
A: 

i would recommend one of the following:

coverage - you can run a coverage tool in the hope of detecting some dead code

caching - cache the dll on the client side on the initial activatio

splitting - split the dll into several smaller dlls, start the application with the bootstrap dll and download the other dlls after the application starts

compilation and linking - use smaller run time library, compile with size optimization, etc. see this link for more suggestions.

compression - if you have data or large resources within the dll, you can compress them and decompress only after the download or at runtime.

geva30
"this link" seems to have gone lost.
Georg Fritzsche
+5  A: 

When you build your DLL, you can pass /MAP to the linker to have it generate a map file containing the addresses of all symbols in the resulting image. You will probably have to do some scripting to calculate the size of each symbol.

Using a "strings" utility to scan your DLL might reveal unexpected or unused printable strings (e.g. resources, RCS IDs, __FILE__ macros, debugging messages, assertions, etc.).

Also, if you're not already compiling with /Os enabled, it's worth a try.

bk1e
+1, the map file looks promising
Georg Fritzsche
To undecorate the names in the map file use undname.exe - http://msdn.microsoft.com/en-us/library/5x49w699%28VS.80%29.aspx
Georg Fritzsche
Very cool. It looks like manual inspection of the map file will give me enough information to get started.
PeterAllenWebb
And for the sake of completeness: use `UndecorateSymbolName()` from dbghelp to undecorate programatically ... http://stackoverflow.com/questions/1617204/undecorate-function-names-with-visual-studio-sdk
Georg Fritzsche
+1  A: 

You can also try to link statically instead of using a dll. Indeed, when the library is linked statically the linker removes all unused functions from the final exe. Sometime the final exe is only slightly bigger and you don't have any more dll.

Rexxar
++ Excellent suggestion.
Mike Dunlavey
+3  A: 

If your end goal is only to trim the size of the DLL, then after tweaking compiler settings, you'll probably get the quickest results by running your DLL through UPX. UPX is an excellent compression utility for DLLs and EXEs; it's also open-source with a non-viral license, so it's okay to use in commercial/closed-source products.

I've only had it turn up a virus warning on the highest compression setting (the brute-force option), so you'll probably be fine if you use a lower setting than that.

Mark Rushakoff
+1  A: 

If your DLL is this big because it's exporting C++ function with exceptionally long mangled names, an alternative is to use a .DEF file to export the functions by ordinal, without name (using NONAME in the .DEF file). Somewhat brittle, but it reduces the DLL size, EXE size and load times.

See e.g. http://home.hiwaay.net/~georgech/WhitePapers/Exporting/Exp.htm

MSalters
+1  A: 

Given that all your .obj files are about the same size, assuming that you're using precompiled headers, try creating an empty obj file and see how large it is. That will give you an idea of the proportion of each .obj that's due to the PCH compilation. The linker will be able to remove all the duplicates there, incidentally. Alternatively you could try disabling PCH so that the obj files will give you a better indication of where the main culprits are.

the_mandrill
+1  A: 

All good suggestions. What I do is get the map file and then just eyeball it. The kind of thing I've found in the past is that a large part of the space is taken by one or more class libraries brought in by the fact that some variable somewhere was declared as having a type that sounded like it would save some coding effort but wasn't really necessary.

Like in MFC (remember that?) they have a wrapper class to go around every thing like controls, fonts, etc. that Win32 provides. Those take a ton of space and you don't always need them.

Another thing that can take a ton of space is collection classes you could manage without. Another is cout I/O routines you don't use.

Mike Dunlavey