【问题标题】:How do YOU reduce compile time, and linking time for Visual C++ projects (native C++)?您如何减少 Visual C++ 项目(原生 C++)的编译时间和链接时间?
【发布时间】:2010-09-26 17:27:12
【问题描述】:

如何减少 VC++ 项目(原生 C++)的编译时间和链接时间?

请说明每条建议是否适用于调试、发布或两者兼而有之。

【问题讨论】:

  • 我希望这是两个问题,一个用于链接,一个用于编译(他在等待链接完成时说)
  • 可能有些答案同样适用于两者
  • 你可以在这个线程中阅读我的帖子。 here

标签: c++ visual-c++ compilation


【解决方案1】:

这对您来说可能听起来很明显,但我们尝试尽可能使用前向声明,即使它需要写出类型所在的长命名空间名称:

// Forward declaration stuff
namespace plotter { namespace logic { class Plotter; } }

// Real stuff
namespace plotter {
    namespace samples {
        class Window {
            logic::Plotter * mPlotter;
            // ...
        };
    }
}

它大大减少了在其他编译器上编译的时间。事实上,它适用于所有配置:)

【讨论】:

  • 你打败了我 =)。我尽量减少包含其他标题的标题,尽可能使用前向引用。
  • 推论是尽可能将包含从头文件移动到实现文件。
  • @Boojum:是的,这以可维护性和可读性为代价加快了速度。我会改用前向声明标题。
  • 或者您的意思是将声明本身放入单独的标头中,例如 标准标头?我不确定这一点,只有在恕我直言时放置一组有限的前向声明才有意义。
  • 喜欢 。我每个库使用一个这样的文件(通常与每个“顶级”命名空间一个相同),并发现拥有不需要的前向声明没有任何成本。这使得下一个开发人员可以轻松地包含一个或两个前向声明文件并获得他们需要的一切。
【解决方案2】:

使用the Handle/Body pattern(有时也称为“pimpl”、“adapter”、“decorator”、“bridge”或“wrapper”)。通过将类的实现隔离到 .cpp 文件中,它们只需要编译一次。大多数更改不需要更改头文件,因此这意味着您可以进行相当广泛的更改,而只需要重新编译一个文件。这也鼓励重构和编写 cmets 和单元测试,因为编译时间减少了。此外,您可以自动分离接口和实现的关注点,从而简化代码的接口。

【讨论】:

  • 这些建议中的大多数都会降低代码的可读性和可维护性......所以如果你只是实现 pimpl idiom 来加快编译速度,请记住权衡取舍。
  • 使用这种模式大大提高了代码的可读性和可维护性,原因我已经给出了
【解决方案3】:

如果您的构建过程中的大多数 .cpp 文件都必须包含大型复杂标头,并且这些标头不经常更改,则可以预编译它们。在具有典型配置的 Visual C++ 项目中,只需将它们包含在 stdafx.h 中即可。这个特性有它的缺点,但是充分利用模板的库往往在头文件中有很多东西,而预编译的头文件是在这种情况下加速构建的最简单方法。

【讨论】:

【解决方案4】:

这些解决方案适用于调试和发布,并且专注于已经庞大且繁琐的代码库。

前向声明是一种常见的解决方案。

分布式建筑,例如 Incredibuild 是一个胜利。

将代码从标头下推到源文件中是可行的。小类、常量、枚举等可能会在头文件中开始,因为它可以在多个编译单元中使用,但实际上它们只在一个编译单元中使用,并且可以移动到cpp 文件。

我尚未阅读但使用过的解决方案是拆分大标题。如果您有一些非常大的标题,请查看它们。它们可能包含相关信息,也可能依赖于许多其他标头。获取不依赖于其他文件的元素...简单的结构、常量、枚举和前向声明,并将它们从the_world.h 移动到the_world_defs.h。您现在可能会发现很多源文件现在只能包含 the_world_defs.h 并避免包含所有这些开销。

Visual Studio 还有一个“显示包含”选项,可以让您了解哪些源文件包含许多头文件以及哪些头文件最常包含。

对于非常常见的包含,请考虑将它们放在预编译的标头中。

【讨论】:

【解决方案5】:

我使用Unity Builds(截屏located here)。

【讨论】:

【解决方案6】:

编译速度问题很有趣,Stroustrup 在他的FAQ 中有这个问题。

【讨论】:

    【解决方案7】:

    我们使用Xoreax's Incredibuild 在多台机器上并行运行编译。

    【讨论】:

    • @Gelldur 修复了链接
    • 嗯,链接时间仍然没有减少:)
    【解决方案8】:

    还有一篇来自 Ned Batchelder 的有趣文章:http://nedbatchelder.com/blog/200401/speeding_c_links.html(关于 Windows 上的 C++)。

    【讨论】:

      【解决方案9】:

      我们的开发机器都是四核的,我们使用Visual Studio 2008 支持并行编译。我不确定是否所有版本的 VS 都可以做到这一点。

      我们有一个包含大约 168 个单独项目的解决方案文件,在我们的四核机器上编译这种方式大约需要 25 分钟,而在我们为暑期学生提供的单核笔记本电脑上大约需要 90 分钟。不完全可比的机器,但你明白了:)

      【讨论】:

      • 它没有记录,但同样的标志 (/MP) 也可以用于 VS 2005
      • /MP 不能很好地用于调试,因为它与增量构建不兼容
      • 不幸的是,链接步骤似乎不平行。
      【解决方案10】:

      在 Visual C++ 中,有一种方法称为 Unity,它通过减少对象模块的数量来显着改善链接时间。

      这涉及连接 C++ 代码,通常按库分组。这当然会使编辑代码变得更加困难,除非你很好地使用它们,否则你会遇到命名空间冲突。它使您无法使用“使用命名空间 foo”;

      我们公司的几个团队有精心设计的系统来获取普通的 C++ 文件并在编译时将它们连接起来作为构建步骤。链接时间的减少是巨大的。

      【讨论】:

      • 以编译时间为代价:如果只更改库中的一行,则必须完全编译它。
      • 但有可能通过以 2 个为一组进行连接,例如,您几乎可以将最坏情况的构建时间减半,而将最佳非平凡情况的构建时间仅增加几个百分点,因为所有的编译时间都花在头文件中的代码上,而不是 cpp 文件中的代码上。所以选择 2
      【解决方案11】:

      另一种有用的技术是blobbing。我认为这与 Matt Shaw 所描述的相似。

      简单地说,您只需创建一个包含其他 cpp 文件的 cpp 文件。您可能有两种不同的项目配置,一种是普通的,一种是 blob。当然,blobbing 会对您的代码施加一些限制,例如未命名命名空间中的类名可能会发生冲突。

      当您更改一个 cpp 文件时,避免在 blob 中重新编译整个代码的一种技术(正如 David Rodríguez 所提到的)是让您的“工作” blob 由最近修改的文件和其他普通 blob 创建。

      我们大部分时间都在工作中使用 blob,它减少了项目构建时间,尤其是链接时间。

      【讨论】:

      • 它的通用名称是“Unity Build” - 有关更多详细信息,请参阅stackoverflow.com/questions/543697/…。这不一定是个好主意。
      • 我们还在工作中使用 blob,使用基于当前在 VCS 中签出的文件的工作 blob(如果您此后重新生成了项目)。请注意,即使不包含相应的文件,它也可能隐藏一些错误,例如使符号可用。如果开发人员忘记包含同一 blob 中的文件,则编译错误只会在无 blob(标准)编译(在 CI 中完成)中弹出,此时开发人员必须添加缺少的包含。
      【解决方案12】:

      编译时间:
      如果您有 IncrediBuild,编译时间将不是问题。如果您没有 IncrediBuild,请尝试“统一构建”方法。它将多个 cpp 文件合并到一个 cpp 文件中,从而减少了整个编译时间。
      链接时间:
      “统一构建”方法也有助于减少链接时间,但作用不大。但是,您可以检查是否启用了“整体全局优化”和“LTCG”,虽然这些标志使程序变快,但它们确实使链接变慢。
      尝试关闭“全局优化”并将 LTCG 设置为“默认”,链接时间可能会减少 5/6。
      (LTCG 代表链接时间码生成)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-03
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多