C++ 是否有技术可以极大地改进C++;3D应用程序的构建时间?

C++ 是否有技术可以极大地改进C++;3D应用程序的构建时间?,c++,c++11,makefile,C++,C++11,Makefile,有许多超薄笔记本电脑,它们既便宜又好用。编程的优点是可以在任何安静舒适的地方进行,因为长时间集中精力是能够进行有效工作的重要因素 我有点老套,我喜欢静态编译的C或C++,这些语言在那些受功率限制的笔记本电脑上,特别是C++ 11和C++ 14,可以编译得很长。 我喜欢做3D编程,我使用的库可能很大,而且不会被原谅:bullet physics、Ogre3D、SFML,更不用说现代IDE的强大需求了 有几种解决方案可以加快构建速度: 解决方案A:不要使用那些大的库,自己想出一些更轻松的方法来减轻

有许多超薄笔记本电脑,它们既便宜又好用。编程的优点是可以在任何安静舒适的地方进行,因为长时间集中精力是能够进行有效工作的重要因素

我有点老套,我喜欢静态编译的C或C++,这些语言在那些受功率限制的笔记本电脑上,特别是C++ 11和C++ 14,可以编译得很长。 我喜欢做3D编程,我使用的库可能很大,而且不会被原谅:bullet physics、Ogre3D、SFML,更不用说现代IDE的强大需求了

有几种解决方案可以加快构建速度:

  • 解决方案A:不要使用那些大的库,自己想出一些更轻松的方法来减轻编译器的负担。编写适当的makefile,不要使用IDE

  • 解决方案B:在别处设置一个建筑服务器,在一台肌肉发达的机器上设置一个makefile,并自动下载生成的exe。我不认为这是一个随意的解决方案,因为你必须以笔记本电脑的CPU为目标

  • < >解决方案C:使用非官方C++模块


还有其他建议吗?

正如Yellow先生在评论中指出的,提高编译时间的最佳方法之一是仔细注意头文件的使用。特别是:

  • 对您不希望更改的任何头使用预编译头,包括操作系统头、第三方库头等
  • 将其他标题中包含的标题数量减少到所需的最小值。
    • 确定头中是否需要包含,或者是否可以将其移动到cpp文件。这有时会引起连锁反应,因为其他人依赖于您为其包含标题,但从长远来看,最好将包含移动到实际需要的位置
    • 使用前向声明的类等通常可以消除包含声明该类的头的需要。当然,您仍然需要在cpp文件中包含头文件,但这种情况只发生一次,而不是每次包含相应的头文件时都发生
  • 使用#pragma一次(如果编译器支持),而不是包含保护符号。这意味着编译器甚至不需要打开头文件来发现包含保护。(当然,许多现代编译器都能帮你解决这个问题。)

一旦控制了头文件,请检查make文件以确保不再存在不必要的依赖项。我们的目标是重建你需要的一切,但不再是。有时人们会犯错误,因为构建太多比构建太少更安全。

编译速度是可以提高的,如果您知道如何提高编译速度的话。仔细考虑项目的设计(尤其是由多个模块组成的大型项目)并对其进行修改总是明智的,这样编译器就可以高效地生成输出。

1。预编译标题。

预编译头是一个普通头(
.h
文件),它包含最常见的声明、typedef和include。在编译过程中,它只被解析一次——在编译任何其他源之前。在此过程中,编译器生成一些内部(很可能是二进制)格式的数据,然后使用这些数据加快代码生成

这是一个示例:

#pragma once

#ifndef __Asx_Core_Prerequisites_H__
#define __Asx_Core_Prerequisites_H__

//Include common headers
#include "BaseConfig.h"
#include "Atomic.h"
#include "Limits.h"
#include "DebugDefs.h"
#include "CommonApi.h"
#include "Algorithms.h"
#include "HashCode.h"
#include "MemoryOverride.h"
#include "Result.h"
#include "ThreadBase.h"
//Others...

namespace Asx
{

    //Forward declare common types
    class String;
    class UnicodeString;

    //Declare global constants
    enum : Enum
    {
        ID_Auto     = Limits<Enum>::Max_Value,
        ID_None     = 0
    };

    enum : Size_t
    {
        Max_Size            = Limits<Size_t>::Max_Value,
        Invalid_Position    = Limits<Size_t>::Max_Value
    };

    enum : Uint
    {
        Timeout_Infinite    = Limits<Uint>::Max_Value
    };

    //Other things...

}

#endif /* __Asx_Core_Prerequisites_H__ */
您真的需要将数据存储为值吗?为什么不这样做:

class BigDataType; //That's enough, #include not required

class Sample
{
protected:
    BigDataType* _data; //So much better now
};
这对于大型产品尤其有利。

3。不要过度使用模板。

元编程是开发人员工具箱中非常强大的工具。但是当它们不是必需的时候,不要尝试使用它们

它们对于特性、编译时评估、静态反射等方面都非常有用。但它们带来了很多麻烦:

  • 错误消息-如果您曾经看到由于不正确使用
    std::
    迭代器或容器(特别是复杂的迭代器或容器,如
    std::unordered_map
    )而导致的错误,那么您就知道这是怎么回事了
  • 可读性-复杂的模板可能很难读取/修改/维护
  • 怪癖-许多技术,模板的使用,并不那么众所周知,所以维护这样的代码可能会更加困难
  • 编译时-现在对我们来说最重要的是:
请记住,如果将函数定义为:

template <class Tx, class Ty>
void sample(const Tx& xv, const Ty& yv)
{
    //body
}
我们的应用程序不断发展,我们需要扩展/更改
Person
定义。我们添加一些新字段,删除其他字段。。。一切都崩溃了:人的大小改变,字段的名称改变。。。大灾变特别是,每个依赖于
人员的定义的客户机代码都需要更改/更新/修复。不太好

但我们可以用聪明的方法来做——隐藏个人的细节:

class Person
{
protected:
    class Details;
    Details* details;
};
现在,我们做了几件好事:

  • 客户端无法创建代码,这取决于如何定义
    Person
  • 只要我们不修改客户端代码使用的公共接口,就不需要重新编译
  • 我们减少了编译时间,因为不再需要提供
    string
    Date
    的定义(在以前的版本中,我们必须为这些类型包含适当的标题,这会增加额外的依赖项)。

5

尽管如此,它更清晰,更不容易出错。这与使用include guards基本相同:

#ifndef __Asx_Core_Prerequisites_H__
#define __Asx_Core_Prerequisites_H__

//Content

#endif /* __Asx_Core_Prerequisites_H__ */
它防止对同一文件进行多次解析。虽然
#pragma once
不是标准的(事实上,没有pragma is-pragma是为特定于编译器的指令保留的),但它得到了相当广泛的支持(例如:VC++、GCC、CLang、ICC),可以不用担心就使用它-编译器应该
class Person
{
protected:
    class Details;
    Details* details;
};
#ifndef __Asx_Core_Prerequisites_H__
#define __Asx_Core_Prerequisites_H__

//Content

#endif /* __Asx_Core_Prerequisites_H__ */
#include "Time.h"
#include "Day.h"
#include "Month.h"
#include "Timezone.h"

class Date
{
protected:
    Time time;
    Day day;
    Month month;
    Uint16 year;
    Timezone tz;

    //...
};
//These are no longer required!
//#include "Time.h"
//#include "Day.h"
//#include "Month.h"
//#include "Timezone.h"

class Date
{
protected:
    class Details;
    Details* details;

    //...
};