map initialization: object code is 50 times larger than source code

I am working in C++ with BCC32. I initialized a map with about 1000 entries like this:

extern map<string, string> city ;
void region_init_0 (void) { 
city["abc01"] = "Brussels" ;
city["xyz03"] = "Liege" ;

The length of the .cpp file is 40 KB. After compilation, I get a .obj file of 2.2 MB. After linking with other modules, the .exe file is also 2 MB longer than before I added the map. I don't understand why I get this ratio of 50 between the length of the object code and the total length of the ASCII strings.

How can I reduce that? I guess that there must be more clever ways to initialize a map that will remain constant during the execution of the program.



Just use an external function and pass the raw cstrings to it:

extern std::map<std::string, std::string> city;

/* somehow make sure it cannot be inlined */
extern void AddCity(const char* const a, const char* const b) __attribute__((__noinline__));

void region_init_0 (void) {

extern void AddCity(const char* const a, const char* const b) {
    city[a] = b;

I simulated your case on my system, and it brought the executable size down to 100K (stripped) from 924K. One difference in the simulation is that you'll export more strings, so the ratio will not be equal.

Have you enabled optimizations in your compiler?

You could perhaps have some code like

typedef std::pair<const char*,const char*> paircstr_t;
const paircstr_t initarr[] = {
  { "abc01", "Brussels" },
  { "xyz02", "Paris" },
  /// etc...
  { (const char*)0, (const char*)0 } // terminating null placeholder

extern map<string, string> city ;
void region_init_0 (void) { 
   for (int i = 0;; i++) {
      const char* curname = initarr[i].first;
      const char* curcity = initarr[i].second;
      if (!curname || !curcity) break;
      map[curname] = curcity;

The object code size might be smaller, but the runtime heap size won't change.

Just a guess: Is operator[] inline? Hopefully you can change this by (un)defining some preprocessor constant. Is the release build larger or smaller than debug?

You've added a lot of code. In the object file, there are not just the strings, but the generated code, and probably debugging information (e.g. line number information) for every line. It all adds up.

This is also a very poor way to do initialize a map; unless it is machine generated code, you don't want to write it. (And while perhaps not an issue here, it means that the map can't be const.) A more typical solution to initialize a map might be something like:

struct MapInitializer
    typedef std::map<std::string, std::string> MapType

    char const* key;
    char const* value;
    operator MapType::value_type() const
        return MapType::value_type(key, value);

static MapInitializer initialValues[] =
    { "abc01", "Brussels" },
    { "xyz03", "Liege"    },
    //  ...

and then:

std::map<std::string, std::string> city(
        std::begin( initialValues ), std::end( initialValues ) );

(If the initialization must be deferred to a later function call, then:

city = std::map<std::string, std::string>(
        std::begin( initialValues ), std::end( initialValues ) );

can be used. But generally, if the map is to be initialized with a compile time constant list, it's best to do it in the definition of the variable, as above.)

Need Your Help

Importing QoH in Odoo 8

import odoo

Documentation for the new version of Odoo (OpenERP) is nearly non-existent. Apparently, the process for importing Quantity on Hand for products has changed, and I can't find anything that describe...

Visual Basic Keydown computation

I've been doing this a couple of days.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.