このコードがg ++でコンパイルするのにとても時間がかかるのはなぜですか?


12

次のコードを検討してください。

template<int i> class A
{
    typedef A<i-1> B;
    B x, y;
};
template<> class A<0> { char m; };
int main()
{
    A<LEVEL> a;
}

次のBashコマンドでg ++によるコンパイルをベンチマークするとき(g ++ 8.3.0を使用)

for ((level=1; level<30; ++level)); do
    echo -n ${level},
    /usr/bin/time -f %U g++ -DLEVEL=$level test.cpp -o /dev/null
done

次の出力が表示されます。

1,0.03
2,0.03
3,0.04
4,0.04
5,0.04
6,0.04
7,0.04
8,0.04
9,0.03
10,0.04
11,0.02
12,0.04
13,0.02
14,0.03
15,0.04
16,0.05
17,0.05
18,0.08
19,0.11
20,0.20
21,0.35
22,0.67
23,1.30
24,2.52
25,5.02
26,10.23
27,19.96
28,40.30
29,80.99

したがって、コンパイル時間は指数関数的ですLEVEL。しかし、に変更B x, y;するB x[2];と、コンパイルは一定の時間(〜30 ms)で発生します。

なぜそれが起こるのですか?私は、コンパイラがそれは知っているので、それを考えB1との両方に同じタイプであるxy、それをコンパイルするのと同じ時間がかかるだろう、x[2]。しかし、何らかの理由でそれは異なって見えます。B(単純にエイリアスされるのではなく)何らかの方法で実現することを強制して、g ++が配列を作成するのと同じくらい簡単に両方の変数を作成できるようにできますか?


1
技術的には正しいが役に立たない(あなたにとって)答え:コンパイラにパッチを当てます。
Botje

5
なぜここに投稿するのですか?Gccには問題を報告するためのBugzillaがあります...ただし、最初に最新バージョンでテストしてください。
Marc Glisse、

@MarcGlisse良い説明や回避策があるといいのですが。私がそのように報告した場合、修正する価値のあるバグと見なされるかどうかはわかりません。
ルスラン

3
コンパイラーがコンパイルに時間がかかりすぎる場合のために、キーワード "compile-time-hog"もあるので、はい、修正する価値があると考えています(これはすぐに実行するという意味ではありません)。したがって、特に指数関数的な動作を行わない別のコンパイラーを見つけた場合(それが回避可能であることがわかっている場合)、報告してください。データベースに非常によく似たものが見つかるかどうかを確認してください。ただし、明らかでない複製を見逃した場合でも問題ありません。
Marc Glisse、

5
@MarcGlisseが報告:gcc.gnu.org/bugzilla/show_bug.cgi?id
Ruslan

回答:


1

あなたのg ++​​インスタンスにバグがあるからです。それはすべきではなく、@ Marc Glisseがコメントしたように、それを報告する必要があります(執筆時に行ったものです)。

次に、質問を削除することをお勧めします(賢明な選択)。またはこの答えを受け入れます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.