C++ のコンパイル時間を短縮するにはどのようなテクニックを使用できますか?
この質問はStack Overflowの質問へのコメントでいくつか出てきましたC++プログラミングスタイル、どんなアイデアがあるのか聞いてみたいと思います。
関連する質問を見ました。C++ のコンパイルにはなぜ時間がかかるのでしょうか?しかし、それだけでは多くの解決策は得られません。
ベストアンサー1
言語技術
ピンプルイディオム
見てみましょうピンプルの慣用句 ここ、 そしてここ、別名不透明なポインタまたはハンドルクラス。コンパイルを高速化するだけでなく、スローしないスワップ関数。Pimpl イディオムを使用すると、ヘッダー間の依存関係を減らし、必要な再コンパイルの量を減らすことができます。
前方宣言
可能な限り、前方宣言コンパイラがそれがSomeIdentifier
構造体かポインターかなどを知る必要があるだけなら、定義全体を含めないでください。そうしないと、コンパイラは必要以上に多くの作業を行うことになります。これは連鎖的な効果を生み、必要以上に遅くなる可能性があります。
の入出力ストリームは、特にビルドの速度を低下させることで知られています。ヘッダー ファイルでストリームが必要な場合は、<iosfwd>
の代わりに#including を試し<iostream>
、<iostream>
実装ファイルでのみヘッダーを #include してください。<iosfwd>
ヘッダーには前方宣言のみが保持されます。残念ながら、他の標準ヘッダーには、それぞれの宣言ヘッダーがありません。
関数シグネチャでは、値渡しよりも参照渡しを優先してください。これにより、ヘッダー ファイルにそれぞれの型定義を #include する必要がなくなり、型を前方宣言するだけで済みます。もちろん、わかりにくいバグを回避するために、非 const 参照よりも const 参照を優先しますが、これは別の質問の問題です。
ガード条件
ガード条件を使用して、ヘッダー ファイルが単一の翻訳単位に複数回含まれないようにします。
#pragma once
#ifndef filename_h
#define filename_h
// Header declarations / definitions
#endif
プラグマと ifndef の両方を使用することで、プレーン マクロ ソリューションの移植性と、ディレクティブの存在下で一部のコンパイラが実行できるコンパイル速度の最適化を実現できますpragma once
。
相互依存を減らす
一般的に、コード設計がモジュール化され、相互依存性が低くなるほど、すべてを再コンパイルする頻度は少なくなります。また、追跡する対象が少なくなるため、コンパイラが個々のブロックに対して同時に実行する必要がある作業量も削減できます。
コンパイラオプション
プリコンパイル済みヘッダー
これらは、多くの翻訳単位に含まれるヘッダーの共通セクションを 1 回コンパイルするために使用されます。コンパイラはこれを 1 回コンパイルし、その内部状態を保存します。その後、その状態をすばやくロードして、同じヘッダー セットを持つ別のファイルをコンパイルする際に有利な状態を維持できます。
プリコンパイルされたヘッダーにはほとんど変更されないものだけを含めるように注意してください。そうしないと、必要以上に頻繁に完全な再構築を行うことになります。言語ヘッダーおよびその他のライブラリ インクルード ファイル。
キャッシュキャッシュ技術を利用して処理を高速化するもう 1 つのユーティリティです。
並列処理を使用する
多くのコンパイラ/IDEは、複数のコア/CPUを使用して同時にコンパイルすることをサポートしています。GNU メイク(通常GCCで使用される)-j [N]
オプションを使用します。Visual Studioでは、複数のプロジェクトを並行してビルドできるようにするオプションが設定にあります。/MP
オプションプロジェクト レベルの並列処理だけでなく、ファイル レベルの並列処理も実現します。
その他の並列ユーティリティ:
最適化レベルを低くする
コンパイラが最適化しようとすればするほど、コンパイラの作業負荷は大きくなります。
共有ライブラリ
.so
あまり頻繁に変更されないコードをライブラリに移動すると、コンパイル時間を短縮できます。共有ライブラリ (または)を使用すると.dll
、リンク時間も短縮できます。
より高速なコンピュータを手に入れる
RAM を増やしたり、ハード ドライブ (SSD を含む) を高速化したり、CPU/コアを増やしたりすると、コンパイル速度に違いが生じます。