如何减少模板繁重的C ++代码的输出大小?

时间:2012-10-14 13:03:33

标签: c++ templates boost-spirit

我有一个很大的问题。我有一个公共库,在我的项目中使用。此库密集使用boost.spiritboost.fusion。不幸的是,图书馆约。 700Mb大小。使用了所有boost.spirit - 重代码,它运行良好。可以采取哪些措施来减少其输出尺寸?是否有一个工具可以帮助确定哪些模板实例化会浪费大部分空间?

起初,我决定将所有精神感知代码移动到cpp文件。其次,我将尝试不同的编译器标志来优化大小。我不知道还能做什么。

更新(详细信息)

我正在使用GNU工具链。巨大的库实际上是一个静态库。使用这个700Mb库的可执行文件大小为200Mb。至少有一半的代码是* .h文件。一些boost.spirit语法(非常模板重的东西)也位于* .h文件中。

干杯!

4 个答案:

答案 0 :(得分:5)

将精神意识代码移动到.cpp文件是一个很好的第一步,虽然你提到在头文件中有精神语法,但它可能是不完整的。

  1. 确保从未将任何语法/规则导出到库外。如果您有典型的include / src目录,则在src目录中移动这些文件(即使标题)。

  2. 将所有这些符号标记为库的内部符号。它们不应该从图书馆外面访问。根据您的编译器有特定的编译指示/属性,在gcc上查找visibility attribute__attribute__ ((visibility ("internal")))。这有助于编译器相应地优化它们,特别是编译器可以发出函数的代码,即使它在给定的调用站点上内联它,以防万一这个函数地址被采用。但是,通过内部可见性,因为它知道代码不会离开对象,所以它可能会忽略该功能。

  3. 我似乎记得有一个标志来融合相同的功能体但似乎无法再找到......

答案 1 :(得分:4)

--ffunction-sections会将每个函数放在自己的细分中。它本身没有用,但链接器可以用--gc-sections删除未使用的部分。现在没有--function-segments这只有在整个源文件未被使用时才会起作用,即具有疯狂的粒度。

显然你需要Matthieu提到的visibility属性,否则库中的所有函数都会因为可见而被“使用”。

答案 2 :(得分:2)

一些建议:

  • 在可能的情况下,尝试重复使用相同的模板实例化(作为一个简单且设计的示例,std::vector<int>std::vector<float>具有相同的内部结构,并且可以只处理它们元素数据作为不透明的4字节blob,因此可以委托给另一个,并且只是作为一个东西包装器,它只是转换回正确的类型,因此向量的内部只需要实例化为一种类型,而不是不止两个。

  • 尝试不同的编译器。一些编译器重用相同的模板实例,它不会影响程序语义,而其他编译实例更保守。

  • 密切关注从库中导出的内容。链接器可以删除未导出且未在内部引用的符号。 (当然,如果你正在构建一个静态库,那么在它被链接到可执行文件之前不会启动。为了减小库本身的大小,你可以尝试将它变成一个动态库)

但最终,听起来你可能只需要使用模板量较少的库。 (或者写一个比你现在更简单的解析器)

答案 3 :(得分:2)

此处已讨论过:why my C++ output executable is so big?

基本上,查找调试符号,订单链接依赖关系,优化等等......