前置き
江添亮のC++入門を参考に、コンパイル済みヘッダー(precompiled header)を使用すると、コンパイル時間にどの程度差が出るか確認する。
コンパイル済みヘッダーとは
事前にコンパイルしたヘッダー
拡張子は
.gch
Sample source
all.h
#include <cstddef>
#include <limits>
#include <climits>
#include <cfloat>
#include <cstdint>
#include <cstdlib>
#include <new>
#include <typeinfo>
#include <exception>
#include <initializer_list>
#include <cstdalign>
#include <stdexcept>
#include <cassert>
#include <cerrno>
#include <system_error>
#include <string>
#if __has_include(<string_view>)
# include <string_view>
#endif
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <iterator>
#include <algorithm>
#include <cfenv>
#include <random>
#include <numeric>
#include <cmath>
#include <iosfwd>
#include <iostream>
#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#if __has_include(<filesystem>)
# include <filesystem>
#endif
#include <cstdio>
#include <cinttypes>
#include <regex>
#include <atomic>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <condition_variable>
#include <future>
using namespace std::literals ;
main.cpp
int main()
{
std::cout << "hello" ;
}
コンパイル済みヘッダー未使用でのコンパイル
まずはコンパイル済みヘッダーを使用せずにコンパイルする。
コンパイル時間は以下のとおりである。
$ time g++ -std=c++20 -Wall -pedantic-errors -include ./all.h -o program ./main.cpp
real 0m1.691s
user 0m0.000s
sys 0m0.015s
コンパイル済みヘッダー使用でのコンパイル
コンパイル済みヘッダーの作成
使用するオプションは-x c++-header
と-o <ヘッダーファイル名>.gch
だ。
-
-x c++-header
オプションでC++ヘッダーとして扱うことをコンパイラーに強制する。 -
-o <ヘッダーファイル名>.gch
で出力ファイルの拡張子をgchにする。
その他一般的なコンパイル時に必要なオプションを追加したコマンドが下記となる。
今回はついでにコンパイル時間も計測している。不要な場合はtime
を削除して使用してください。
$ time g++ -std=c++20 -Wall -pedantic-errors -x c++-header -o all.h.gch ./all.h
real 0m3.313s
user 0m0.000s
sys 0m0.015s
-xオプションについて
-x
オプションの引数は他にも色々ある。たとえばC言語で同じ事がしたければ、c-header
を使用すれば良い。
c
c-header: precompiled header file
cpp-output
c++
c++-header
c++-cpp-output
objective-c
objective-c-header
objective-c-cpp-output
objective-c++
objective-c++-header
objective-c++-cpp-output
assembler
assembler-with-cpp
ada
f77
f77-cpp-input
f95
f95-cpp-input
go
brig参照:gcc -x
コンパイル
実際にコンパイル済みヘッダーを使用してコンパイルしてみる。
gccはヘッダーファイルを使う時、同名の.gch
ファイルが存在する時、そちらをコンパイル済みヘッダーとして使用することでヘッダーファイルの処理を省略する。実行結果は下記となる。確かに少し早い。
$ time g++ -std=c++20 -Wall -pedantic-errors -include ./all.h -o program ./main.cpp
real 0m0.515s
user 0m0.000s
sys 0m0.015s
コンパイル時間比較
コンパイル時間を比較してみる。このプログラムだとコンパイル時間が3分の1ほどになっている。
コンパイル済みヘッダー未使用 | コンパイル済みヘッダー使用 |
---|---|
real 0m1.691s | real 0m0.515s |
まとめ
勉強するにあたって、コンパイルの度に時間をかけるのは非効率だと思う。
そういう意味ではコンパイル済みヘッダーはどんどん使っていくのが良いだろう。