代码合并包括将整个源代码复制到一个文件中。
例如,它是由SQLite完成的,以减少编译时间并提高结果可执行文件的性能。在这里,它生成一个184 K行代码的文件。
我的问题不是关于编译时间(已经用这个问题回答了),而是关于可执行文件的效率。
SQLite开发人员说:
除了使SQLite更容易合并到其他项目之外,合并还使它运行得更快。当代码包含在单个翻译单元(如合并中)时,许多编译器能够对代码进行额外的优化。当我们使用合并来编译SQLite而不是单个源文件时,我们已经测量到了5%到10%的性能改进。这样做的缺点是,额外的优化通常采用函数内联的形式,这会使生成的二进制图像的大小更大。
据我所知,这要归功于程序间优化(IPO),这是编译器进行的一种优化。
GCC开发人员也这样说(谢谢@nwp提供的链接):
编译器根据其对程序的知识执行优化。一次将多个文件编译成单个输出文件模式允许编译器在编译每个文件时使用从所有文件中获得的信息。
但他们并没有谈论最终的收益。
除了SQLite的数据外,是否有任何数据证实或反驳了这样的说法:在与gcc合作时,与合并会产生比没有合并的IPO 更快的可执行性?
作为一个附带的问题,对于这种优化,做代码合并还是将所有.cpp (或.c)文件包含到一个文件中是一回事吗?
发布于 2016-08-11 14:30:33
源代码文件的组织不会“产生更有效的二进制文件”,从多个源文件检索的速度也是微不足道的。
无论大小大小,版本控制系统都将接受任何文件的增量。
通常,像这些组件这样的独立组件是单独编译的,以生成包含关联对象代码的二进制库:源代码不会每次被重新编译。当“应用程序A”使用被更改的“库B”时,必须重新链接“应用程序A”,但如果库的API没有更改,则不必重新编译它。
而且,就库本身而言,如果它由(数百个)单独的源文件组成,那么在重新链接库之前,只需要重新编译已更改的文件。(任何Makefile都能做到这一点。)如果源代码是“一件大事”,你必须每次都重新编译,这可能需要很长时间.基本上是浪费时间。
从库中获取对象代码有两种方法(一旦生成.)可以合并到可执行文件中:静态链接和动态链接。如果使用静态链接,库的必要部分将被复制到可执行文件中。但是,并不是全部。库文件在运行可执行文件时不一定存在。
如果使用动态链接,则整个库存在于一个单独的文件中(例如,.DLL或.so),该文件必须在运行时存在,但将由同时使用它的每个应用程序共享。
我建议您主要将此视为源代码管理问题,而不是赋予任何技术或运行时优势的东西。(不会。)我觉得很难找到这样做的令人信服的理由。
https://stackoverflow.com/questions/38899001
复制相似问题