Dela via


Jämför rubrikenheter, moduler och förkompilerade rubriker

Tidigare skulle du inkludera standardbiblioteket med ett direktiv som #include <vector>. Det är dock dyrt att inkludera huvudfiler eftersom de bearbetas på nytt av varje källfil som innehåller dem.

Förkompilerade huvuden (PCH) introducerades för snabb kompilering genom att översätta dem en gång och återanvända resultatet. Men förkompilerade rubriker kan vara svåra att underhålla.

I C++20 introducerades moduler som en betydande förbättring av huvudfiler och förkompilerade rubriker.

Rubrikenheter introducerades i C++20 som ett sätt att tillfälligt överbrygga klyftan mellan huvudfiler och moduler. De ger några av modulernas hastighets- och robusthetsfördelar medan du migrerar koden för att använda moduler.

Sedan introducerade standardbiblioteket C++23 stöd för att importera standardbiblioteket som namngivna moduler. Det här är det snabbaste och mest robusta sättet att använda standardbiblioteket.

För att hjälpa dig att reda ut de olika alternativen jämför den här artikeln den traditionella #include metoden med förkompilerade rubriker, rubrikenheter och import av namngivna moduler.

Följande tabell ordnas med kompilatorbearbetningshastighet och robusthet, med #include långsammaste och minst robusta, och import är den snabbaste och mest robusta.

Metod Sammanfattning
#include En nackdel är att de exponerar makron och intern implementering. Intern implementering exponeras ofta som funktioner och typer som börjar med ett understreck. Det är en konvention som anger att något är en del av den interna implementeringen och inte bör användas.

Rubrikfiler är bräckliga eftersom ordningen på #includes kan ändra beteende eller bryta kod och påverkas av makrodefinitioner.

Långsam kompilering av rubrikfiler. Särskilt när flera filer innehåller samma fil eftersom huvudfilen sedan bearbetas flera gånger.
Förkompilerad rubrik En fördefinierad rubrik (PCH) förbättrar kompileringstiden genom att skapa en ögonblicksbild av kompilatorns minne av en uppsättning huvudfiler. Det här är en förbättring när det gäller att återskapa huvudfiler upprepade gånger.

PCH-filer har begränsningar som gör dem svåra att underhålla.

PCH-filer är snabbare än #include men långsammare än import.
Huvudenheter Det här är en ny funktion i C++20 som gör att du kan importera "väl utformade" headerfiler som moduler.

Rubrikenheter är snabbare än #include, och är enklare att underhålla, betydligt mindre och även snabbare än förkompilerade huvudfiler (PCH).

Rubrikenheter är ett "in-between"-steg som är avsett att hjälpa till att övergå till namngivna moduler i fall där du förlitar dig på makron som definierats i huvudfiler, eftersom namngivna moduler inte exponerar makron.

Rubrikenheter är långsammare än att importera en namngiven modul.

Rubrikenheter påverkas inte av makrodefinierade värden om de inte anges på kommandoraden när rubrikenheten är inbyggd – vilket gör dem mer robusta än huvudfiler.

Rubrikenheter exponerar makron och den interna implementering som definierats i dem precis som rubrikfilen gör, vilket namngivna moduler inte gör.

Som en ungefärlig uppskattning av filstorleken kan en PCH-fil på 250 MB representeras av en 80 megabytes rubrikenhetsfil.
Modules Det här är det snabbaste och mest robusta sättet att importera funktioner.

Stöd för att importera moduler introducerades i C++20. C++23-standardbiblioteket introducerar de två namngivna modulerna som beskrivs i det här avsnittet.

När du importerar stdfår du standardnamnen, till exempel std::vector, std::coutmen inga tillägg, inga interna hjälpverktyg som _Sort_unchecked, och inga makron.

Importordningen spelar ingen roll eftersom det inte finns några makroeffekter eller andra biverkningar.

Som en ungefärlig uppskattning av filstorleken kan en PCH-fil på 250 MB representeras av en 80 megabytes rubrikenhetsfil, som kan representeras av en modul på 25 megabyte.

Namngivna moduler går snabbare eftersom kompilatorn genererar en strukturerad representation av källkoden som kan läsas in snabbt när modulen importeras när en namngiven modul kompileras till en .ifc fil och en .obj fil. Kompilatorn kan utföra en del arbete (t.ex. namnmatchning .ifc ) innan filen genereras på grund av hur namngivna moduler är orderoberoende och makrooberoende, så det här arbetet behöver inte göras när modulen importeras. När en rubrikfil däremot används med #includemåste dess innehåll förbearbetas och kompileras om och om igen i varje översättningsenhet.

Förkompilerade rubriker, som är ögonblicksbilder av kompilatorns minne, kan minska dessa kostnader, men inte lika bra som namngivna moduler.

Om du kan använda C++20-funktioner och C++23-standardbiblioteket i din app använder du namngivna moduler.

Om du kan använda C++20-funktioner men vill övergå över tid till moduler använder du rubrikenheter under tiden.

Om du inte kan använda C++20-funktioner kan du använda #include och överväga förkompilerade rubriker.

Se även

Förkompilerade huvudfiler
Översikt över moduler i C++
Självstudie: Importera C++-standardbiblioteket med hjälp av moduler
Genomgång: Importera STL-bibliotek som rubrikenheter
Genomgång: Skapa och importera rubrikenheter i dina Visual C++-projekt