提高c ++编译速度的最佳方法

时间:2016-08-07 10:40:36

标签: c++ oop design-patterns cmake

我有一个C ++项目,它有50多个类。这些类可以分为7个不同的文件夹,但大多数这些类在代码的不同部分使用。 当我使用Netbeans进行开发时,它会编译并链接所有目标文件。因此,它将所有文件链接到其他需要大量时间的文件。 为了解决这个问题,我使用了CMake,并尝试单独编译每个类别,使每个类别依赖于所有必需的类别。但经过一段时间后,大量的未定义参考......"当我在其他模块中包含一些标题时开始。 向我提出的新解决方案是为每个类别创建一个Facade类来处理每个类别操作。但是为了删除include依赖,有人说我不能使用每个类的公共函数。相反,我必须获取目标对象并将其提供给Facade类的函数,以便在其他类中为我执行它。例如,假设这种情况:

ClassA.h:
            Class A{
                int calculateSomething(string str);
            }

  ClassA.cpp:
         int A::calculateSomething(string str){
              if(str="1") return 1;
         }

 ClassAFacade.h
            Class A; 


            Class AFacade{
                static int calculateSomething(Class A*, string str);    
                static A* getA();
            }

ClassAFacade.cpp
            #include "A.h" 

            int AFacade::calculateSomething(Class A*, string str){
                return A->calculateSomething(str);
            }

           A* AFacade::getA(){
                return new A();
            }


ClassB.h:
        #include "AFacade.h"

        Class B{
            void someMethod();
        }

 ClassB.cpp:
            #include "B.h"
        void B::someMethod(){
                 A* aptr = AFacade::getA();
                 int tmp = AFacade::calculateSomething(aptr,"test");
         }

虽然这个解决方案似乎解决了我的问题,但这很奇怪。因为它实际上阻止了函数调用,并将此权限授予某些特定类(7类Facade类)。 你认为这个解决方案是正确的吗?你能为解决这个问题提供更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

您可能希望为所有类编写接口,这些接口需要在类别外部可见。 C ++中的接口是纯抽象类。还为每个接口声明一个工厂方法。在工厂方法的实现文件中,包括类的实际实现:

// file: a_interface.h
namespace catA {
class AInterface {
  public:
    virtual ~AInterface() = default;
    int calculateSomething(string str) = 0;
};
std::unique_ptr<AInterface> createA();
}  // namespace catA

// file: a.h
include "a_interface.h"
namespace catA {
class A : public AInterface
{
  public:
    int calculateSomething(string str) override;
};
}  // namespace catA

// file: a_interface.cpp
#include "a.h"
namespace catA {
std::unique_ptr<AInterface> createA()
{
  return std::make_unique<A>();
}
}  // namespace catA

// file: a.cpp
#include "a.h"
namespace catA {
int A::calculateSomething(string str)
{
  // do stuff
}
}  // namespace catA

然后,您可以在a_interface.hpp的任何位置加入A,通过createA()获取实例,而不必处理实施细节:

#include "b.h"
#include "a_interface.h"
namespace catB {
void B::someMethod() {
  auto aptr = catA::createA();
  int tmp = aPtr->calculateSomething("test");
}
}  // namespace catB

使用CMake,您可以为每个类别创建单独的共享(或静态)库,并在相应的库之间建立链接。或者你create object libraries没有明确的联系 在这两种情况下,您最终都会为每个类别制作单独的制作目标。在代码更改时, make (或 Ninja 或其他)将找出自己重建所需的目标。

答案 1 :(得分:0)

根据我以前的合同,一个包含数百个开发人员和超过一百万个LOC(代码行)的大项目(主要是C ++),早上的构建时间通常可以“重建”所有'不到1小时。到中午,重建时间通常都超过3个小时。这些编译分布在多台机器上,具有快速的网络硬件。

这也是你使用Make文件的原因...一个做得好的Make文件可以避免重建没有改变的东西。

我提出,提高构建性能的最佳方法是1)处理make文件(如果使用它们,可能构建'脚本'),2)在尽可能多的处理器上分配构建/核心,你可以。 3)仅使用计算机和文件服务器之间可用的最快硬件(以太网)连接。