8

我们有一个庞大的代码库,多年来成功地使用了 boost::signals。我们最近迁移到 boost v1.54 并决定由于 boost::signals 已被弃用,我们将切换到 boost::signals2。

我们看到的问题是编译时间非常可怕。例如,一个小的 .cpp 文件现在需要 20 多秒,而过去需要 4 秒。

同样,我们的一个库(大型)过去需要大约 10 分钟才能生成,现在需要长达一个小时。我到处搜索有关如何通过预编译头文件、宏等来改进这一点的文档,但还没有找到任何可以大大改善这种情况的东西。

在 procmon 中查看 cl.exe 会发现 boost::signals2 和 mpl 库中有大量 IO。

在这一点上,我们不需要信号2 提供的线程安全性,我们即将拔掉“升级”的插头并恢复为信号。在我们放弃之前,有没有人对此有任何建议或经验?

我们正在使用带有大量 RAM/磁盘/等的 VS2012。

4

1 回答 1

6

在我从事的一个项目中,所有升压信号的使用都被压缩了,因此前向声明就足够了。这显着减少了编译时间,因为仅在实际需要时才解析信号 2 定义。boost::signals2::signal该类没有提供公共成员,而是有一个私有的 std::unique_pointer 成员,并提供了一个公共的 connectToX 函数,该函数返回一个 std::unique_pointer 对象。

class Subject {
public:
    boost::signals2::signal<void (int)> valueChanged;
    void setValue(int x) {
        valueChanged(x);
    }
};

class A {
public:
    A(Subject& subject): conn( subject.sig.connect( [&](int x) {this->onChange(x);} ) {}
    ~A() {conn.disconnect();}
private:
    void onChange(x) {}

    boost::signals2::connection conn;
};

然后成为只有前向声明且不包含 boost 信号2 标头的标头:

// Header file
class Subject {
public:
    std::unique_ptr<boost::signals2::connection> connect(std::function<void (int)> observer);

private:
    class Impl;
    std::unique_ptr<Impl> mImpl;
};

对信号不感兴趣的类现在不需要解析信号2 标头。值得注意的是,根据我的经验,大部分时间不是在编译器中解析,而是在链接器中。每个使用 boost 信号的编译单元都包含许多实例化函数,这些函数会生成调试信息,最后必须由链接器消除。鉴于 MS 链接器是单线程的并且非常慢,这就是花时间做 IO 的地方。SSD 在这里提供了很好的加速。

于 2014-03-30T16:27:20.960 回答