Warum dauert das Kompilieren dieses Codes mit g ++ so lange?

12

Betrachten Sie den folgenden Code:

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

Beim Benchmarking der Kompilierung durch g ++ mit dem folgenden Bash-Befehl (mit 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

Ich erhalte folgende Ausgabe:

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

Die Kompilierungszeit ist also in exponentiell LEVEL. Wenn ich jedoch zu wechsle B x, y;, B x[2];erfolgt die Kompilierung in konstanter Zeit (~ 30 ms).

Warum passiert das? Ich dachte, da der Compiler weiß, dass dies Bfür beide ein und derselbe Typ ist xund yes genauso lange dauern würde wie das Kompilieren x[2]. Aber aus irgendeinem Grund sieht es anders aus. Kann ich irgendwie Bdie Realisierung erzwingen (im Gegensatz zu einfachem Aliasing), damit g ++ beide Variablen genauso einfach erstellen kann wie das Array?

Ruslan
quelle
1
Eine technisch korrekte, aber (für Sie) nutzlose Antwort: Patchen Sie den Compiler.
Botje
5
Warum würdest du das hier posten? Gcc hat einen Bugzilla zum Melden von Problemen ... Stellen Sie jedoch sicher, dass Sie zuerst mit der neuesten Version testen.
Marc Glisse
@MarcGlisse Ich hoffte, dass es eine gute Erklärung oder eine Problemumgehung geben könnte. Ich bin mir nicht sicher, ob es sich um einen Fehler handelt, der es wert ist, behoben zu werden, wenn ich ihn als solchen gemeldet habe.
Ruslan
3
Sie haben sogar ein Schlüsselwort "compile-time-hog" für Fälle, in denen das Kompilieren des Compilers zu lange dauert. Ja, sie halten es für eine Korrektur wert (was nicht bedeutet, dass sie es sofort tun werden). Wenn Sie also einen anderen Compiler sehen, der nicht das exponentielle Verhalten aufweist (Sie wissen also, dass es vermeidbar ist), melden Sie es bitte. Überprüfen Sie vielleicht, ob Sie etwas sehr Ähnliches in der Datenbank sehen, aber es ist in Ordnung, wenn Sie ein nicht offensichtliches Duplikat verpassen.
Marc Glisse
5
@MarcGlisse berichtete: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Ruslan

Antworten:

1

Weil es einen Fehler in Ihrer g ++ - Instanz gibt. Dies sollte nicht der Fall sein, und wie @Marc Glisse kommentierte, sollten Sie dies melden (was Sie zum Zeitpunkt des Schreibens getan haben).

Vielleicht möchten Sie Ihre Frage dann löschen (klügere Wahl). Oder akzeptiere diese Antwort.

Heyji
quelle