13

我有一个大问题。我有一个通用库,在我的项目中使用。该库大量使用boost.spiritboost.fusion. 不幸的是,图书馆大约是。700Mb 大小。所有的boost.spirit-heavy 代码都被使用并且运行良好。可以采取哪些步骤来减小其输出大小?是否有工具可以帮助确定哪些模板实例化浪费了大部分空间?

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

更新(详情)

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

干杯!

4

4 回答 4

5

将精神感知代码移动到.cpp文件是一个很好的第一步,尽管您提到头文件中有精神语法,但它可能不完整。

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

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

  3. 我似乎记得有一个标志可以融合相同的功能体,但似乎再也找不到了……

于 2012-10-14T15:25:32.097 回答
4

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

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

于 2012-10-15T08:35:59.060 回答
2

几点建议:

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

  • 尝试不同的编译器。一些编译器在不会影响程序语义的情况下重用相同的模板实例化,而另一些则更为保守。

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

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

于 2012-10-14T13:42:19.297 回答
2

这里已经讨论过:为什么我的 C++ 输出可执行文件这么大?

基本上,寻找调试符号、链接依赖的顺序、优化等等......

于 2012-10-14T13:46:55.547 回答