logo

Inline funktioner i C++

C++ giver indlejrede funktioner til at reducere funktionskaldet overhead. En inline-funktion er en funktion, der udvides på linje, når den kaldes. Når inline-funktionen kaldes, bliver hele koden for inline-funktionen indsat eller erstattet ved punktet for inline-funktionskaldet. Denne substitution udføres af C++ compileren på kompileringstidspunktet. En inline-funktion kan øge effektiviteten, hvis den er lille.

Syntaks:



inline return-type function-name(parameters) { // function code }>
Inline funktion i c++

Husk, at inlining kun er en anmodning til compileren, ikke en kommando. Compileren kan ignorere anmodningen om inlining.

Compileren må ikke udføre inlining under sådanne omstændigheder som:

  1. Hvis en funktion indeholder en løkke. ( for, mens og gør-mens )
  2. Hvis en funktion indeholder statiske variable.
  3. Hvis en funktion er rekursiv.
  4. Hvis en funktionsreturtype er en anden end void, og returneringssætningen ikke findes i en funktionstekst.
  5. Hvis en funktion indeholder en switch eller goto-sætning.

Hvorfor bruges inline-funktioner?

Når programmet udfører funktionskaldsinstruktionen, gemmer CPU'en hukommelsesadressen for instruktionen efter funktionskaldet, kopierer argumenterne for funktionen på stakken og overfører til sidst kontrollen til den specificerede funktion. CPU'en udfører derefter funktionskoden, gemmer funktionsreturværdien i en foruddefineret hukommelsesplacering/register og returnerer kontrollen til den kaldende funktion. Dette kan blive overhead, hvis udførelsen af ​​funktionen er mindre end skifttiden fra den kaldende funktion til den kaldede funktion (callee).



For funktioner, der er store og/eller udfører komplekse opgaver, er overheaden for funktionskaldet normalt ubetydelig sammenlignet med den tid, funktionen tager at køre. Men for små, almindeligt anvendte funktioner er den tid, der er nødvendig for at foretage funktionskaldet, ofte meget mere end den tid, der kræves til rent faktisk at udføre funktionens kode. Denne overhead opstår for små funktioner, fordi udførelsestiden for en lille funktion er mindre end koblingstiden.

Inline funktioner Fordele:

  1. Funktionsopkald overhead forekommer ikke.
  2. Det gemmer også overhead af push/pop-variabler på stakken, når en funktion kaldes.
  3. Det gemmer også overhead for et tilbagekald fra en funktion.
  4. Når du inline en funktion, kan du aktivere compileren til at udføre kontekstspecifik optimering på funktionens krop. Sådanne optimeringer er ikke mulige for normale funktionskald. Andre optimeringer kan opnås ved at overveje strømmene i den kaldende kontekst og den kaldte kontekst.
  5. En inline-funktion kan være nyttig (hvis den er lille) til indlejrede systemer, fordi inline kan give mindre kode end funktionen kaldet preamble og return.

Inline funktion Ulemper:

  1. De tilføjede variabler fra den inlinede funktion bruger yderligere registre. Efter in-lining-funktionen, hvis variabeltallet, der skal bruge registret, stiger, kan de skabe overhead på registervariable ressourceudnyttelse. Dette betyder, at når den inline funktions krop erstattes ved punktet af funktionskaldet, indsættes det samlede antal variabler, der bruges af funktionen. Så antallet af registre, der skal bruges til variablerne, vil også blive øget. Så hvis efter funktion inlining variable tal stiger drastisk, så ville det helt sikkert forårsage overhead på registerudnyttelse.
  2. Hvis du bruger for mange inline-funktioner, vil størrelsen af ​​den binære eksekverbare fil være stor på grund af duplikeringen af ​​den samme kode.
  3. For meget inlining kan også reducere din instruktionscache-hitrate, og dermed reducere hastigheden af ​​instruktionshentning fra cachehukommelsens til den primære hukommelse.
  4. Inline-funktionen kan øge kompileringstiden overhead, hvis nogen ændrer koden inde i inline-funktionen, så skal alle kaldende lokationer kompileres igen, fordi kompilatoren ville være forpligtet til at erstatte al koden igen for at afspejle ændringerne, ellers vil den fortsætte med den gamle funktionalitet.
  5. Inline-funktioner er muligvis ikke nyttige for mange indlejrede systemer. For i indlejrede systemer er kodestørrelse vigtigere end hastighed.
  6. Inline-funktioner kan forårsage thrashing, fordi inlining kan øge størrelsen på den binære eksekverbare fil. At tæske i hukommelsen får computerens ydeevne til at forringes. Følgende program demonstrerer brugen af ​​inline-funktionen.

Eksempel:

C++






#include> using> namespace> std;> inline> int> cube(>int> s) {>return> s * s * s; }> int> main()> {> >cout <<>'The cube of 3 is: '> << cube(3) <<>' '>;> >return> 0;> }>

>

>

Produktion

The cube of 3 is: 27>

Inline funktion og klasser

Det er også muligt at definere inline-funktionen inde i klassen. Faktisk er alle funktioner defineret inde i klassen implicit inline. Alle begrænsningerne for inline-funktioner anvendes således også her. Hvis du eksplicit skal erklære en inline-funktion i klassen, skal du blot erklære funktionen inde i klassen og definere den uden for klassen ved hjælp af inline-nøgleordet.

Syntaks:

class S { public: inline int square(int s) // redundant use of inline { // this function is automatically inline // function body } };>

Ovenstående stil betragtes som en dårlig programmeringsstil. Den bedste programmeringsstil er bare at skrive prototypen af ​​funktionen inde i klassen og angive den som en inline i funktionsdefinitionen.

For eksempel:

class S { public: int square(int s); // declare the function }; inline int S::square(int s) // use inline prefix { }>

Eksempel:

C++




// C++ Program to demonstrate inline functions and classes> #include> using> namespace> std;> class> operation {> >int> a, b, add, sub, mul;> >float> div>;> public>:> >void> get();> >void> sum();> >void> difference();> >void> product();> >void> division();> };> inline> void> operation ::get()> {> >cout <<>'Enter first value:'>;> >cin>> a;> >cout <<>'Enter second value:'>;> >cin>> b;> }> inline> void> operation ::sum()> {> >add = a + b;> >cout <<>'Addition of two numbers: '> << a + b <<>' '>;> }> inline> void> operation ::difference()> {> >sub = a - b;> >cout <<>'Difference of two numbers: '> << a - b <<>' '>;> }> inline> void> operation ::product()> {> >mul = a * b;> >cout <<>'Product of two numbers: '> << a * b <<>' '>;> }> inline> void> operation ::division()> {> >div> = a / b;> >cout <<>'Division of two numbers: '> << a / b <<>' '>;> }> int> main()> {> >cout <<>'Program using inline function '>;> >operation s;> >s.get();> >s.sum();> >s.difference();> >s.product();> >s.division();> >return> 0;> }>

>

java konventioner navngivning
>

Produktion:

Enter first value: 45 Enter second value: 15 Addition of two numbers: 60 Difference of two numbers: 30 Product of two numbers: 675 Division of two numbers: 3>

Hvad er der galt med makroen?

Læsere, der er fortrolige med C-sproget, ved, at C-sproget bruger makro. Forprocessoren erstatter alle makrokald direkte i makrokoden. Det anbefales altid at bruge inline-funktionen i stedet for makroen. Ifølge Dr. Bjarne Stroustrup er skaberen af ​​C++ makroer næsten aldrig nødvendige i C++, og de er tilbøjelige til fejl. Der er nogle problemer med brugen af ​​makroer i C++. Makroen kan ikke få adgang til private medlemmer af klassen. Makroer ligner funktionskald, men det er de faktisk ikke.

Eksempel:

C++




// C++ Program to demonstrate working of macro> #include> using> namespace> std;> class> S {> >int> m;> public>:> >// error> #define MAC(S::m)> };>

>

>

Produktion:

Error: '::' may not appear in macro parameter list #define MAC(S::m)>

C++ compiler kontrollerer argumenttyperne for inline funktioner og nødvendige konverteringer udføres korrekt. Forprocessormakroen er ikke i stand til at gøre dette. En anden ting er, at makroerne styres af præprocessoren, og inline-funktioner styres af C++-kompileren. Husk: Det er rigtigt, at alle funktioner defineret inde i klassen implicit er inline, og C++ compileren vil udføre inline kald af disse funktioner, men C++ compileren kan ikke udføre inline, hvis funktionen er virtuel. Årsagen kaldes til en virtuel funktion løses ved kørsel i stedet for kompileringstid. Virtuel betyder at vente til runtime og inline betyder under kompilering, hvis compileren ikke ved hvilken funktion der vil blive kaldt, hvordan kan den udføre inlining? En anden ting at huske er, at det kun er nyttigt at gøre funktionen inline, hvis den tid, der bruges under et funktionskald, er mere sammenlignet med funktionskroppens udførelsestid.

Et eksempel, hvor inline-funktionen slet ikke har nogen effekt:

inline void show() { cout << 'value of S = ' << S << endl; }>

Ovenstående funktion tager relativt lang tid at udføre. Generelt bør en funktion, der udfører en input-output (I/O) operation, ikke defineres som inline, fordi den bruger en betydelig mængde tid. Teknisk inlining af show()-funktionen er af begrænset værdi, fordi den tid, I/O-sætningen vil tage, langt overstiger overheaden for et funktionskald. Afhængigt af den compiler du bruger, kan compileren vise dig en advarsel, hvis funktionen ikke er udvidet inline.

Programmeringssprog som Java & C# understøtter ikke inline-funktioner. Men i Java kan compileren udføre inlining, når den lille endelige metode kaldes, fordi endelige metoder ikke kan tilsidesættes af underklasser, og kaldet til en endelig metode løses på kompileringstidspunktet.

I C# kan JIT compiler også optimere kode ved at inlinere små funktionskald (som at erstatte kroppen af ​​en lille funktion, når den kaldes i en loop). Den sidste ting at huske på er, at inline-funktioner er en værdifuld funktion i C++. Korrekt brug af inline-funktioner kan give ydeevneforbedring, men hvis inline-funktioner bruges vilkårligt, kan de ikke give bedre resultater. Med andre ord, forvent ikke en bedre ydeevne af programmet. Gør ikke alle funktioner inline. Det er bedre at holde inline funktioner så små som muligt.