如果包括"assert.h"的每个文件都需要很长的编译时间吗?
Does it take long compilation time if every files including "assert.h"?
根据Mats Petersson的结果,我做了一些测试。我通过定义宏来打开和关闭断言的工作是不必要的。我的结论是:
- 包括标准标头,如
<cassert>
、<vector>
、<memory>
等,编译时间很少。我们不需要关心。 - 在包含您自己的文件时要小心。包括那些真正需要的,因为依赖关系需要在更改依赖关系后重新编译。
- 包含类库的集合标头时要小心,例如
<QWidgets>
(Qt 标头以包含其所有小部件)。这在编译中花费了大量时间。
[原文]
如果每个文件都包含"assert.h",编译时间是否很长?我认为在"math.h"或其他常见文件中也有类似的问题。我不喜欢预编译的标题。当我有一个 Vector3D 类时,就会发生这种情况,该类表示 3D 空间中具有 x、y、z 分量的向量。该类几乎无处不在。我有一个名为 component(int i)
的函数,其中断言 i
介于 0 和 2 之间。出于性能原因,我不将其实现放在 cpp 文件中。因此,"assert.h"几乎无处不在。
#pragma once
#include <assert.h>
/// A vector in a 3D space with 3 components: x, y, and z.
class Vector3D
{
public:
Vector3D(float x = 0, float y = 0, float z = 0)
{
m_component[0] = x;
m_component[1] = y;
m_component[2] = z;
}
float x() const {return m_component[0];}
float y() const {return m_component[1];}
float z() const {return m_component[2];}
void setX(float x) {m_component[0] = x;}
void setY(float y) {m_component[1] = y;}
void setZ(float z) {m_component[2] = z;}
float component(int i) const
{
assert(i >= 0 && i < 3);
return m_component[i];
}
float& component(int i)
{
assert(i >= 0 && i < 3);
return m_component[i];
}
private:
float m_component[3];
};
受Floris Velleman的启发,我添加一个文件来定义我的ASSERT,以打开和关闭它。它需要使用断言在代码中将assert
更改为ASSERT
。谢谢。
#ifdef USE_ASSERT
# include <assert.h>
# define ASSERT(statement) assert(statement)
#else
# define ASSERT(statement)
#endif
所有标头都使用相同的包含模型,这非常慢。某些标头可能比其他标头更复杂,但通常,您不包含不需要的标头。
是的,在我的机器上,每个文件需要多花 0.03 秒(总共 0.1 秒,超过 30 个文件,包含 #include <assert.h>
或 //#include <assert.h>
以及大约 90 行的大注释来填写文件。我将其复制了 30 次到单独的 .c 文件中,并使用 gcc -c *.c
进行编译。
但是,这几乎是"什么都没有"编译的。如果我们取而代之的是一些真实的C++代码,那么编译器必须"思考"一下,会发生什么:
基线(源代码 xx.cpp - 独立程序中大约 280 行C++代码,复制到名为 xx1 的文件 30 次.cpp .. xx30.cpp,使用 g++ -O2 -c *.cpp
编译):
7.722s 7.730s 7.660s
在列表末尾添加#include <cassert>
7.734s 7.652s 7.676s
我不认为这是一个重大变化。我敢肯定,如果您在每个头文件中都#include <assert.h>
,并包含数百或数千个头文件,其中都包含 assert.h,也许它会有所作为。但我怀疑任何人都能够衡量一个真实项目的真正差异。
标准标头assert.h
(您使用的是尖括号而不是引号,所以我假设您谈论的是标准 C assert 标头)是所有标准 C 库中最小的标头之一,因此在这种情况下,这真的无关紧要。断言的有用性比您可能获得的任何速度都重要。
注意:使用 in C++ cassert
代替 assert.h
。
另一方面,像iostream这样又大又复杂的标题...
#ifndef AssertIncluded
#define AssertIncluded
#include "assert.h"
#endif
不是 100% 确定语法,但这可能会摆脱双重包含的东西。至于速度,编译时间会根据必须发生的事情的数量而增加。包含更多文件意味着:"更长的编译时间"。
- 使用简单类型列表实现的指数编译时间.为什么
- 在已经使用Git的情况下减少编译时间
- C++常量数组的编译时间较长
- 编译时间文本到数字转换 (atoi)
- 在C++中执行 N 阶乘编译时间的 3 种不同/相同方法
- DLLexport 类模板实例(专用化),减少了仅标头模板库的编译时间
- 替换枚举以最大化编译时间检查的最佳方法
- 不同C++功能的编译时间
- 在预编译标头中实例化模板会缩短编译时间吗?
- 使用 SCons 提取每个编译单元的编译时间
- 将 lambda 函数转换为另一个编译单元中的普通函数会缩短编译时间吗?
- std :: Invoke_result_t编译时间语法错误
- 模板;constexpr;编译时间
- 如何实现声明功能-C 11,编译时间
- 如何减少编译时间:在包含未触及的头文件的情况下
- C++编译时间类型确定
- 特征:返回对具有编译时间尺寸检查的矩阵块的引用
- 在编译时间定义多个派生类
- 在编译时间创建查找表
- C 函数在编译时间返回类型