如果包含“assert.h”的每个文件都需要很长的编译时间吗?

时间:2013-02-01 21:46:24

标签: c++ compilation

根据Mats Petersson的结果,我做了一些测试。我没有必要通过定义宏来打开和关闭断言。我的结论是:

  1. 包括标准标题,例如<cassert><vector><memory>等,只需要很少的编译时间。我们不需要关心。
  2. 小心包含自己的文件。包括那些真正需要的,因为依赖需要在更改依赖后重新编译。
  3. 在包含类库的集合头时要小心,例如<QWidgets>(Qt头包含其所有小部件)。这需要花费大量时间进行编译。
  4. [原帖]

    如果每个文件都包含“assert.h”,是否需要很长的编译时间?我认为关于“math.h”或其他常见文件的类似问题。我不喜欢预编译的标题。当我有一个Vector3D类来表示具有x,y,z分量的3D空间中的矢量时,会发生这种情况。该课程几乎用于所有地方。我有一个名为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更改为ASSERT。感谢。

    #ifdef USE_ASSERT
    # include <assert.h>
    # define ASSERT(statement) assert(statement)
    #else
    # define ASSERT(statement)
    #endif
    

4 个答案:

答案 0 :(得分:5)

所有标题使用相同的包含模型,这非常慢。某些标题可能比其他标题更复杂,但一般情况下,您不包含不需要的标题。

答案 1 :(得分:3)

是的,在我的机器上,每个文件需要0.03秒(总共0.1秒,超过30个文件,包含#include <assert.h>//#include <assert.h>以及大约90行的大评论文件输出。我将30次复制到单独的.c文件中,并使用gcc -c *.c进行编译。

但是,这几乎没有“编译”。如果我们改为采用一些真正的C ++代码,那么编译器必须“思考”一下,会发生什么:

Baseline(source xx.cpp - 独立程序中大约280行C ++代码,复制30次到名为xx1.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,也许它会有所作为。但我怀疑任何人都能衡量真实项目的真正差异。

答案 2 :(得分:2)

标准标题assert.h(你使用尖括号而不是引号,所以我假设你在谈论标准的C断言标题)是所有标准C库中最小的标题之一,所以在这种情况下它真的没关系。断言的有用性比你可能获得的速度更重要。

注意:在C ++中使用cassert代替assert.h

另一方面像iostream那样大而复杂的标题......

答案 3 :(得分:1)

 #ifndef AssertIncluded
 #define AssertIncluded
 #include "assert.h"
 #endif

不是100%肯定语法,但这可能会摆脱双重包括事情。至于速度,编译时间会根据必须发生的事情的数量而增加。包含更多文件意味着:“更长的编译时间”。