前処理ツールによって生成され、プロジェクトにコンパイルされたいくつかの大きな静的データ テーブル (構造体の配列) がある C++ プロジェクトがあります。今まで VC++ 2008 を使用していましたが、2010 に移行する準備をしていて、これらのデータ テーブルのコンパイルに突然非常に長い時間がかかっています。
例として、そのようなテーブルの 1 つには約 3,000 のエントリがあり、それぞれがいくつかの int とポインタを含む構造体であり、すべて静的に初期化されています。この 1 つのファイルは、VC++ 2008 ではコンパイルに約 15 秒かかりましたが、VC++ 2010 では 30分かかります!
実験として、このテーブルを 8 つのテーブルに均等に分割し、それぞれを独自の .cpp ファイルに分割してみました。それぞれ 20 ~ 30 秒でコンパイルされます。これは、コンパイラ内の何かがこれらのテーブルの長さで O(n^2) であると私に思わせます。
cl.exe のメモリ使用量は約 400 MB で横ばいになり (私のマシンには 12 GB の RAM が搭載されています)、いったん横ばいになると I/O アクティビティが見られないため、これはディスク キャッシュの問題ではないと思います。
ここで何が起こっているのか誰にも分かりますか? 正常なコンパイル時間に戻すために無効にできるコンパイラ機能はありますか?
以下は、テーブル内のデータのサンプルです。
// cid (0 = 0x0)
{
OID_cid,
OTYP_Cid,
0 | FOPTI_GetFn,
NULL,
0,
NULL,
(PFNGET_VOID) static_cast<PFNGET_CID>(&CBasic::Cid),
NULL,
CID_Basic,
"cid",
OID_Identity,
0,
NULL,
},
// IS_DERIVED_FROM (1 = 0x1)
{
OID_IS_DERIVED_FROM,
OTYP_Bool,
0 | FOPTI_Fn,
COptThunkMgr::ThunkOptBasicIS_DERIVED_FROM,
false,
NULL,
NULL,
NULL,
CID_Basic,
"IS_DERIVED_FROM",
OID_Nil,
0,
&COptionInfoMgr::s_aFnsig[0],
},
// FIRE_TRIGGER_EVENT (2 = 0x2)
{
OID_FIRE_TRIGGER_EVENT,
OTYP_Void,
0 | FOPTI_Fn,
COptThunkMgr::ThunkOptBasicFIRE_TRIGGER_EVENT,
false,
NULL,
NULL,
NULL,
CID_Basic,
"FIRE_TRIGGER_EVENT",
OID_Nil,
0,
NULL,
},
// FIRE_UNTRIGGER_EVENT (3 = 0x3)
{
OID_FIRE_UNTRIGGER_EVENT,
OTYP_Void,
0 | FOPTI_Fn,
COptThunkMgr::ThunkOptBasicFIRE_UNTRIGGER_EVENT,
false,
NULL,
NULL,
NULL,
CID_Basic,
"FIRE_UNTRIGGER_EVENT",
OID_Nil,
0,
NULL,
},
ご覧のとおり、さまざまな int と enum に加えて、いくつかのリテラル文字列、関数ポインター、および他の静的データ テーブルへのポインターが含まれています。