【问题标题】:Compile times with boost::signals2 very slow使用 boost::signals2 的编译时间非常慢
【发布时间】:2013-08-01 21:44:33
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 你使用的是预编译头文件吗?
  • Signals2 使用可变参数模板,它们在 VS2012 中以高成本进行仿真。已在 VS2013 中修复。从 Boost 适应到 VS2013 登陆你的桌面,给它几个月的时间。
  • @HansPassant 感谢您提供的信息,我没有考虑过。鉴于我们等待 VS2013 是不可行的,您认为恢复信号库的最佳做法是什么?就像现在一样,由于编译速度慢,代码无法使用。
  • 你已经知道答案了,问我也没用。我的建议物有所值。
  • 您能否提供一些代码来说明您如何使用信号?我们的项目使用 boost::signals2 并且我们被困在 VS2005 上,我还没有遇到这个问题。我们正在使用预编译的头文件。

标签: c++ performance boost visual-studio-2012 compilation


【解决方案1】:

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

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 在这里提供了很好的加速。

【讨论】:

  • 感谢您的反馈。这是一个非常好的主意(尽管不幸的是这种舞蹈是必要的)。我们没有考虑在我们的案例中使用 pimpl,主要是因为使用非常广泛,以至于变化会很大。另一个问题是信号的客户端有时会使用 scoped_connection 范例。我们目前正在将我们的项目文件升级到 VS2013,所以我有兴趣看看上面@Hans Passant 的 cmets 是否属实。
  • 是的,pimpl 使得使用信号变得相当复杂,特别是因为您必须返回 unique_ptrs 与连接。我对 VS2013 的结果非常感兴趣,尽管我目前不在 Windows 平台上工作。我不会期望有太大的改进,因为链接器没有得到很大的改进,这就是我们花费构建时间的地方(以及编写具有大量增强信号实例化的 pdb 文件)。您可以使用 cl /Bt+ 或 link /time+ 来获取一些构建时间测量值。
猜你喜欢
  • 2017-02-05
  • 2017-01-15
  • 2012-12-18
  • 2010-09-08
  • 2012-06-13
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多