map初始化:目标代码比源代码大50倍

时间:2011-11-11 08:31:12

标签: c++ map initialization constants

我使用BCC32在C ++中工作。我初始化了一个包含大约1000个条目的地图,如下所示:

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

.cpp文件的长度为40 KB。编译后,我得到一个2.2 MB的.obj文件。与其他模块链接后,.exe文件也比我添加地图前长2 MB。我不明白为什么我在目标代码的长度和ASCII字符串的总长度之间得到50的比率。

我该如何减少?我想必须有更聪明的方法来初始化一个在程序执行期间保持不变的地图。

感谢。

4 个答案:

答案 0 :(得分:3)

您是否在编译器中启用了优化

你可能有一些像

这样的代码
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;
   }
}

目标代码大小可能更小,但运行时堆大小不会改变。

答案 1 :(得分:2)

只是一个猜测:运营商[]内联吗?希望你可以通过(un)定义一些预处理器常量来改变它。发布版本是否比调试更大或更小?

答案 2 :(得分:1)

你添加了很多代码。在目标文件中,不仅仅是 字符串,但生成的代码,可能还有调试信息 (例如,行号信息)每行。这一切都加起来。

这也是初始化地图的一种非常糟糕的方式;除非是 机器生成的代码,你不想写它。 (虽然也许 这里不是问题,这意味着地图不能是const。)更多 初始化地图的典型解决方案可能是:

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"    },
    //  ...
};

然后:

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

(如果初始化必须推迟到以后的函数调用,那么:

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

可以使用。但通常情况下,如果要使用a初始化地图 编译时间常量列表,最好在定义中执行 变量,如上所述。)

答案 3 :(得分:1)

只需使用外部函数并将原始cstrings传递给它:

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) {
    AddCity("abc01","Brussels");
    AddCity("xyz03","Liege");
    ...
}

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

我在我的系统上模拟了你的情况,它将可执行文件的大小从924K减少到100K(剥离)。模拟的一个不同之处在于您将导出更多字符串,因此该比率将不相等。