VC++ プロジェクト (ネイティブ C++) のコンパイル時間とリンク時間をどのように短縮しますか?
各提案がデバッグ、リリース、またはその両方に適用されるかどうかを指定してください。
VC++ プロジェクト (ネイティブ C++) のコンパイル時間とリンク時間をどのように短縮しますか?
各提案がデバッグ、リリース、またはその両方に適用されるかどうかを指定してください。
当たり前のように聞こえるかもしれませんが、型が含まれる長い名前空間名を書き出す必要がある場合でも、可能な限り前方宣言を使用するようにしています。
// Forward declaration stuff
namespace plotter { namespace logic { class Plotter; } }
// Real stuff
namespace plotter {
namespace samples {
class Window {
logic::Plotter * mPlotter;
// ...
};
}
}
他のコンパイラでのコンパイル時間も大幅に短縮されます。実際、それはすべての構成に適用されます:)
ハンドル/ボディ パターン(「pimpl」、「adapter」、「decorator」、「bridge」、または「wrapper」とも呼ばれます)を使用します。クラスの実装を .cpp ファイルに分離することで、一度コンパイルするだけで済みます。ほとんどの変更では、ヘッダー ファイルを変更する必要はありません。つまり、1 つのファイルを再コンパイルするだけで、かなり広範な変更を行うことができます。これにより、コンパイル時間が短縮されるため、コメントや単体テストのリファクタリングや書き込みも促進されます。さらに、インターフェースと実装の問題を自動的に分離するため、コードのインターフェースが簡素化されます。
ビルドプロセスのほとんどの.cppファイルに含める必要があり、あまり頻繁に変更されない大きな複雑なヘッダーがある場合は、それらをプリコンパイルできます。一般的な構成のVisualC++プロジェクトでは、これは単にstdafx.hにそれらを含めるだけの問題です。この機能には欠点がありますが、テンプレートを最大限に活用するライブラリでは、ヘッダーに多くのものが含まれる傾向があります。その場合、プリコンパイル済みヘッダーがビルドを高速化する最も簡単な方法です。
これらのソリューションは、デバッグとリリースの両方に適用され、すでに大きくて扱いにくいコードベースに焦点を合わせています。
前方宣言は一般的な解決策です。
Incredibuildなどの分散型の構築が効果的です。
ヘッダーからソースファイルにコードをプッシュすることは機能します。小さなクラス、定数、列挙型などは、複数のコンパイルユニットで使用できたという理由だけでヘッダーファイルで始まる場合がありますが、実際には1つでのみ使用され、cppファイルに移動できます。
私が読んでいないが使用した解決策は、大きなヘッダーを分割することです。非常に大きなヘッダーがいくつかある場合は、それらを確認してください。それらには関連情報が含まれている場合があり、他の多くのヘッダーに依存している場合もあります。他のファイルに依存しない要素を取得します...単純な構造体、定数、列挙型、および前方宣言を、からthe_world.h
に移動しますthe_world_defs.h
。これで、多くのソースファイルに含めることができるようにthe_world_defs.h
なり、すべてのオーバーヘッドを含めることを回避できるようになりました。
Visual Studioには、[インクルードを表示]オプションもあり、どのソースファイルに多くのヘッダーが含まれているか、どのヘッダーファイルが最も頻繁にインクルードされているかを知ることができます。
非常に一般的なインクルードについては、コンパイル済みヘッダーに入れることを検討してください。
Unity Builds(ここにあるスクリーンキャスト)を使用しています。
Xoreax の Incredibuildを使用して、複数のマシンでコンパイルを並行して実行します。
コンパイル速度の質問は興味深いので、Stroustrup のFAQに記載されています。
また、Ned Batchelder の興味深い記事: http://nedbatchelder.com/blog/200401/speeding_c_links.html (Windows 上の C++ について)。
私たちの開発マシンはすべてクアッドコアであり、並列コンパイルをサポートする Visual Studio 2008 を使用しています。VS のすべてのエディションでこれができるかどうかはわかりません。
約 168 の個々のプロジェクトを含むソリューション ファイルがあり、この方法でコンパイルすると、夏の学生に提供するシングル コア ラップトップでは約 90 分かかるのに対し、クアッド コア マシンでは約 25 分かかります。正確に匹敵するマシンではありませんが、アイデアはわかります:)
Visual C ++には、オブジェクトモジュールの数を減らすことでリンク時間を大幅に改善する、Unityと呼ばれる方法があります。
これには、通常はライブラリごとにグループ化されたC++コードの連結が含まれます。もちろん、これによりコードの編集がはるかに難しくなり、うまく使用しないと名前空間の衝突が発生します。「名前空間fooの使用」を使用できなくなります。
当社のいくつかのチームは、通常のC ++ファイルを取得し、ビルドステップとしてコンパイル時にそれらを連結するための精巧なシステムを持っています。リンク時間の短縮は非常に大きくなる可能性があります。
もう 1 つの便利な手法はブロブです。Matt Shaw の説明に似ていると思います。
簡単に言えば、他の cpp ファイルをインクルードする 1 つの cpp ファイルを作成するだけです。通常のプロジェクトと BLOB の 2 つの異なるプロジェクト構成がある場合があります。もちろん、ブロブはコードにいくつかの制約を課します。たとえば、名前のない名前空間のクラス名が衝突する可能性があります。
1 つの cpp ファイルを変更するときに (David Rodríguez が述べたように) blob 内のコード全体を再コンパイルすることを回避する 1 つの手法は、最近変更されたファイルと他の通常の blob から作成された「作業用」blob を持つことです。
ほとんどの場合、仕事でブロブを使用しており、プロジェクトのビルド時間、特にリンク時間を短縮しています。
コンパイル時間:
IncrediBuild があれば、コンパイル時間は問題になりません。IncrediBuild をお持ちでない場合は、「unity ビルド」方法をお試しください。複数の cpp ファイルを単一の cpp ファイルに結合するため、コンパイル時間全体が短縮されます。
リンク時間:
「ユニティ ビルド」方式もリンク時間の短縮に貢献しますが、それほど多くはありません。ただし、「全体のグローバル最適化」と「LTCG」が有効になっているかどうかを確認できますが、これらのフラグはプログラムを高速にしますが、リンクは低速にします。
「Whole Global Optimization」をオフにして、LTCG を「Default」に設定すると、リンク時間が 5/6 短縮される可能性があります。
(LTCG は Link Time Code Generation の略です)