【问题标题】:Slow Compile Time with Boost + GCC + precompiled headerBoost + GCC + 预编译头文件编译时间慢
【发布时间】:2012-06-13 02:42:34
【问题描述】:

运行:gcc 版本 4.2.1(Apple Inc. build 5664)

我创建了一个带有默认预编译头文件的苹果 XCode 项目。它似乎很慢,一个没有主要功能的琐碎主文件不包含任何代码需要6秒才能编译,这是我升级到新的SSD驱动器之后。我在笔记本电脑上,但我对升级到工作站会缓解我的问题持保留意见。如果我关闭预编译头文件,那么主文件将在一秒钟内编译。似乎使用预编译的标头会对所有文件造成不利影响。这种延迟让我想避免编译和试验不好的代码。这是我在预编译头文件中包含的内容:

#pragma once

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <valarray>
#include <vector>

#include <boost/smart_ptr/scoped_ptr.hpp>
#include <boost/smart_ptr/scoped_array.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/shared_array.hpp>
#include <boost/smart_ptr/make_shared.hpp>  
#include <boost/smart_ptr/weak_ptr.hpp>
#include <boost/smart_ptr/intrusive_ptr.hpp>

#include <boost/regex.hpp>
#include <boost/thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/bind/apply.hpp>
#include <boost/bind/protect.hpp>
#include <boost/bind/make_adaptable.hpp>

#include <boost/asio.hpp>
//#include <boost/asio/ssl.hpp>


#include <boost/property_tree/ptree.hpp>
#include <boost/random.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/time_zone_base.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>

我没有包含精神,这确实使编译时间上升。

【问题讨论】:

  • 所以一个“没有主要功能的普通主文件不包含代码”比一个包含上面列出的所有包含的项目需要更少的时间来编译?不应该这样吗?
  • 另外,我对预编译头文件的理解是,它们只倾向于节省编译时间,否则它们会通过来自多个来源的includes 重复编译。这不是你的情况,所以我想你使用预编译头文件的编译时间与不使用的情况类似。也就是说,您不会通过使用预编译的标头来获得太多收益。您确实应该将您的包含限制在特定于源文件的基础上。
  • 这是什么意思:“这种延迟让我想避免编译和试验不好的代码。”?

标签: c++ gcc boost compilation precompiled


【解决方案1】:

GCC 的预编译头文件以一种非常特殊的方式工作。在任何给定的源文件中只能使用 一个 预编译的头文件。使用-H 显示给定的头文件是否使用预编译版本。

此外,您必须使用与使用它的源文件完全相同的编译器标志来编译头文件。

设置 PCH 环境的典型方法如下:

ma​​in.cpp:

#include "allheaders.hpp"

int main() { /* ... */ }

allheaders.hpp:

#include <algorithm>
// ... everything you need

编译:

g++ $CXXFLAGS allheaders.hpp                 # 1
g++ $CXXFLAGS -H -c -o main.o main.cpp       # 2
g++ $LDFLAGS -o myprogram main.o             # 3

在第 1 步之后,您应该会得到一个文件 allheaders.hpp.gch,它应该非常大。在步骤 #2 中,-H 标志应该产生额外的输出,告诉您正在使用预编译的头文件。步骤 #3 链接可执行文件。

这个想法是第 1 步可能需要很长时间,但第 2 步应该会变得更快。

【讨论】:

  • 我已经分析了 GCC 命令,它引用了一个 308 MB 的伪文本文件,该文件似乎是经过处理的预编译头文件。每个源文件都会自动包含预编译的头文件,有些人似乎没有得到,并引入了大约 6 秒的延迟。我不记得 Visual Studio 有这个问题,尽管使用 VS 我总是在更强大的工作站上运行它。当我更改文件中的一个字母时,6 秒的延迟时间是不可接受的,并且在开发周期中浪费了数分钟/小时/天的时间。
  • 好吧,您应该对要预编译哪些标头有所了解。当然,您不应该有一个千篇一律的 PCH。理想情况下,您应该为 每个 源文件单独制作一个单独的“所有标题”标题。实际上,我会为那些实际实现所有繁重的 Boost 内容的文件保留这种处理方式。
  • 我几乎在任何地方都使用 boost,所以不将它们放入 PCH 只会导致单个文件编译缓慢。我开始认为这台笔记本电脑和软件对于严肃的 C++ 开发来说太慢了。这对 Cocoa 来说很好,但 Boost 及其大量使用模板和元编程是一个杀手。
  • 看到您的预编译头文件,您可以将其中的一些 Boost Utilities 重构为它们自己的小实现文件。对于某些任务,Boost 几乎是 #define#include 之间的一小部分代码,就像 scoped_ptr&lt;&gt; 可以在它自己的小标题中实现,(几乎)没有依赖关系,也没有依赖于编译器的决定,没有汗水。重新组合和重构 Boost 实用程序为我节省了大约 35% 的编译时间和大约 80% 的“阅读源代码的头痛”时间。
猜你喜欢
  • 2012-09-08
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 2017-03-29
  • 1970-01-01
相关资源
最近更新 更多