8

何年もの間、boost::signals をうまく使用してきた大規模なコードベースがあります。最近、boost v1.54 に移行し、boost::signals が廃止されたため、boost::signals2 に切り替えることにしました。

私たちが見ている問題は、コンパイル時間が恐ろしいことです。たとえば、小さな .cpp ファイルは、以前は 4 秒かかっていたところ、20 秒以上かかるようになりました。

同様に、以前は生成に約 10 分かかっていたライブラリ (大) の 1 つが、現在では最大 1 時間かかります。プリコンパイルされたヘッダーやマクロなどを使用してこれを改善する方法に関するドキュメントをあちこち検索しましたが、状況を大幅に改善するものはまだ見つかりません。

procmon で cl.exe を表示すると、boost::signals2 および mpl ライブラリへの大量の IO が明らかになります。

この時点で、signals2 が提供するスレッド セーフは必要ありません。「アップグレード」のプラグを抜いて、シグナルに戻ろうとしています。あきらめる前に、これに関する提案や経験はありますか?

十分なRAM /ディスクなどを備えたVS2012を使用しています。

4

1 に答える 1

6

私が取り組んだプロジェクトでは、前方宣言で十分であるように、すべてのブースト信号の使用法がにきびでした。これにより、実際に必要な場合にのみ signal2 定義が解析されるため、コンパイル時間が大幅に短縮されます。パブリック メンバーを提供する代わりに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;
};

次に、前方宣言のみを含むヘッダーになり、ブースト シグナル 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;
};

シグナルに関心がないクラスは、signals2 ヘッダーを解析する必要がなくなりました。私の経験では、ほとんどの時間はコンパイラではなくリンカでの解析に費やされていることに注意してください。ブースト信号を使用するすべてのコンパイル ユニットには、デバッグ情報を生成する多くのインスタンス化された関数が含まれており、最後にリンカによって削除する必要があります。また、MS リンカがシングルスレッドで非常に遅いことを考えると、ここで IO の実行に時間が費やされます。SSD は、ここで素晴らしいスピードアップを提供しました。

于 2014-03-30T16:27:20.960 に答える