Vorteile von Inline-Funktionen in C++?

Lesezeit: 11 Minuten

Was sind die Vor-/Nachteile der Verwendung von Inline-Funktionen in C++? Ich sehe, dass es nur die Leistung für den Code erhöht, den der Compiler ausgibt, aber mit den heutigen optimierten Compilern, schnellen CPUs, riesigem Speicher usw. (nicht wie in den 1980er Jahren, wo der Speicher knapp war und alles in 100 KB Speicher passen musste) was Vorteile haben sie heute wirklich?

  • Dies ist eine jener Fragen, bei denen das allgemeine Wissen falsch ist. Jeder hat mit der Standard-Comp Sci-Antwort geantwortet. (Inlining spart Kosten für Funktionsaufrufe, erhöht aber die Codegröße). Müll. Es bietet einen einfachen Mechanismus für den Compiler, um weitere OPTIMIERUNGEN anzuwenden.

    – Martin York

    1. Oktober 2008 um 16:12 Uhr

  • Dies ist eine dieser Antworten, die sich als Kommentare ausgeben. Wenn Ihnen eine der geposteten Antworten nicht gefällt, posten Sie Ihre eigene Antwort und sehen Sie, wie es läuft.

    – Dave Van den Eynde

    2. März 2010 um 14:18 Uhr

  • Die Grundlage dieser Frage ist fehlerhaft. C++-Inline-Funktionen haben wenig mit Compilern zu tun, die während der Kompilierung Inline-Funktionen ausführen. es ist schade, dass inline ein C++-Schlüsselwort ist und dass Inlining eine Compiler-Optimierungstechnik ist. Siehe diese Frage „wann soll ich das Keyword schreiben inline für eine Funktion/Methode” für die richtige Antwort.

    – geschickt_code

    24. März 2011 um 22:37 Uhr

  • @JoseVega Dein Link wurde verstümmelt – der aktuelle Link ist exforsys.com/tutorials/c-plus-plus/inline-functions.html

    Benutzer146043

    1. Mai 2014 um 12:25 Uhr

Vorteile

  • Indem Sie Ihren Code dort einfügen, wo er benötigt wird, verbringt Ihr Programm weniger Zeit mit dem Funktionsaufruf und gibt Teile zurück. Es soll Ihren Code schneller machen, auch wenn er größer wird (siehe unten). Das Inlining trivialer Accessoren könnte ein Beispiel für effektives Inlining sein.
  • Indem Sie es als Inline markieren, können Sie eine Funktionsdefinition in eine Header-Datei einfügen (dh sie kann in mehrere Kompilierungseinheiten eingefügt werden, ohne dass sich der Linker beschwert).

Nachteile

  • Es kann Ihren Code größer machen (z. B. wenn Sie Inline für nicht triviale Funktionen verwenden). Als solches könnte es Paging provozieren und Optimierungen des Compilers zunichte machen.
  • Es unterbricht leicht Ihre Kapselung, weil es das Interne Ihrer Objektverarbeitung offenlegt (aber das würde auch jedes “private” Mitglied tun). Das bedeutet, dass Sie in einem PImpl-Muster kein Inlining verwenden dürfen.
  • Es unterbricht leicht Ihre Kapselung 2: C++-Inlining wird zur Kompilierzeit aufgelöst. Das bedeutet, sollten Sie den Code der Inline-Funktion ändern, müssten Sie den gesamten Code neu kompilieren, um sicherzustellen, dass er aktualisiert wird (aus dem gleichen Grund vermeide ich Standardwerte für Funktionsparameter).
  • Wenn es in einem Header verwendet wird, vergrößert es Ihre Header-Datei und verwässert somit interessante Informationen (wie die Liste einer Klassenmethode) mit Code, der den Benutzer nicht interessiert (das ist der Grund, warum ich Inline-Funktionen innerhalb einer Klasse, definiert sie aber in einem Header nach dem Klassenhauptteil und niemals innerhalb des Klassenhauptteils).

Inline-Magie

  • Der Compiler kann die Funktionen, die Sie als inline markiert haben, einbetten oder nicht; es kann sich auch entscheiden, Funktionen einzubetten, die zum Zeitpunkt der Kompilierung oder Verknüpfung nicht als inline markiert sind.
  • Inline funktioniert wie ein vom Compiler gesteuertes Kopieren/Einfügen, was sich deutlich von einem Präprozessor-Makro unterscheidet: Das Makro wird zwangsweise inliniert, verschmutzt alle Namensräume und den gesamten Code, ist nicht leicht zu debuggen und wird sogar ausgeführt wenn der Compiler es als ineffizient eingestuft hätte.
  • Jede Methode einer Klasse, die innerhalb des Hauptteils der Klasse selbst definiert ist, wird als “inlined” betrachtet (auch wenn der Compiler immer noch entscheiden kann, sie nicht zu inlinen
  • Virtuelle Methoden sollen nicht inlinierbar sein. Manchmal, wenn der Compiler den Typ des Objekts sicher kennen kann (dh das Objekt wurde innerhalb desselben Funktionskörpers deklariert und konstruiert), wird sogar eine virtuelle Funktion eingebettet, da der Compiler den Typ des Objekts genau kennt.
  • Template-Methoden/-Funktionen sind nicht immer inline (ihr Vorhandensein in einem Header macht sie nicht automatisch inline).
  • Der nächste Schritt nach “Inline” ist die Template-Metaprogrammierung. Dh durch “Inlining” Ihres Codes zur Kompilierzeit kann der Compiler manchmal das Endergebnis einer Funktion ableiten … So kann ein komplexer Algorithmus manchmal auf eine Art reduziert werden return 42 ; Aussage. Das ist für mich extremes Inlining. Es passiert selten im wirklichen Leben, es verlängert die Kompilierungszeit, bläht Ihren Code nicht auf und macht Ihren Code schneller. Aber wie der Gral, versuchen Sie nicht, es überall anzuwenden, weil die meisten Verarbeitungen nicht auf diese Weise gelöst werden können … Trotzdem ist das trotzdem cool …
    😛

  • Sie sagten, es bricht leicht Ihre Kapselung. Erklären Sie es bitte anhand eines Beispiels?

    – Destruktor

    6. September 2015 um 13:59 Uhr

  • @PravasiMeet: Es ist C++. Angenommen, Sie liefern eine DLL/gemeinsam genutzte Bibliothek an einen Client, der dagegen kompiliert. Die Inline-Funktion foo, die die Mitgliedsvariable X verwendet und die Arbeit Y erledigt, wird in den Code des Clients eingebettet. Angenommen, Sie müssen eine aktualisierte Version Ihrer DLL liefern, in der Sie die Member-Variable in Z geändert und zusätzlich zu Work Y ein Work YY hinzugefügt haben. Der Client kopiert einfach die DLL in sein Projekt und BOOM, weil der Code von foo in ihrer Binärdatei ist nicht der aktualisierte Code, den Sie geschrieben haben … Obwohl der Client keinen legalen Zugriff auf Ihren privaten Code hat, macht Inlining ihn ziemlich “öffentlich”.

    – Paercebal

    7. September 2015 um 8:38 Uhr

  • @paercebal In Bezug auf Ihren vorletzten Aufzählungspunkt können Sie ein Beispiel dafür geben, wann eine Funktionsvorlage ist nicht in der Reihe? Ich dachte, sie wären immer inline, obwohl ich jetzt keine Referenz zur Hand habe (ein einfacher Test scheint dies jedoch zu bestätigen).

    – Konrad Rudolf

    22. Juni 2016 um 9:37 Uhr

  • @KonradRudolph In n4594 sehe ich: 3.2/6: There can be more than one definition of [..] inline function with external linkage [..] non-static function template. Am 5.1.5/6 For a generic lambda, the closure type has a public inline function call operator member template. Und bei 7.1.2/2: the use of inline keyword is to declare an inline function wo es ein Vorschlag ist, den Funktionsrumpf am Aufrufpunkt zu inlinen. Ich schließe daraus, dass Inline-Funktionen und Funktionsvorlagen, selbst wenn sie sich gleich verhalten können, immer noch getrennte, orthogonale Begriffe sind, die gemischt werden können (dh Inline-Funktionsvorlage).

    – Paercebal

    10. Juli 2016 um 10:08 Uhr


  • Kapselung defekt? Wieso das? Kapselung ist für die Programmierer, nicht für die eigentlichen Objekte im Speicher. zu diesem Zeitpunkt interessiert es niemanden. Selbst wenn Sie eine Bibliothek verteilen, kann der Compiler selbst entscheiden, ob er dies inline tun möchte oder nicht. Wenn Sie also am Ende eine neue Bibliothek erhalten, müssen Sie einfach alles neu kompilieren, was die Funktionen und Objekte aus dieser Bibliothek verwendet.

    – FalkoGer

    2. April 2019 um 6:36 Uhr


Inline-Funktionen sind schneller, da Sie keine Dinge wie Parameter und die Rücksendeadresse auf den Stapel schieben und von ihm entfernen müssen. es macht Ihre Binärdatei jedoch etwas größer.

Macht es einen signifikanten Unterschied? Auf moderner Hardware für die meisten nicht merklich genug. Aber es kann einen Unterschied machen, was für manche Leute genug ist.

Das Markieren von etwas Inline gibt Ihnen keine Garantie dafür, dass es Inline sein wird. Es ist nur ein Vorschlag an den Compiler. Manchmal ist dies nicht möglich, z. B. wenn Sie eine virtuelle Funktion haben oder wenn es sich um eine Rekursion handelt. Und manchmal entscheidet sich der Compiler einfach, es nicht zu verwenden.

Ich könnte sehen, dass eine Situation wie diese einen nachweisbaren Unterschied macht:

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);

  • Wie ich vermutet habe, macht Inlining keinen Unterschied zu dem oben Gesagten. Kompiliert mit gcc 4.01. Version 1 gezwungen Inlining zu verwenden: 48.318u 1.042s 5:51.39 99.4% 0+0k 0+0io 0pf+0w Version 2 erzwungen kein Inlining 348.311u 1.019s 5:52.31 99.1% 0+0k 0+0io 0pf+0w Dies ist ein gutes Beispiel dafür, wo Allgemeinwissen falsch ist.

    – Martin York

    28. September 2008 um 20:38 Uhr

  • Während der Anruf selbst tatsächlich wichtig ist, ist dies nur der geringfügige Gewinn, den Sie durch die Verwendung von Inline erzielen. Der große Gewinn besteht darin, dass der Compiler jetzt sieht, wo sich Zeiger nicht gegenseitig aliasieren, wo Variablen des Aufrufers im Aufgerufenen landen und so weiter. Daher kommt es mehr auf die folgende Optimierung an.

    – Johannes Schaub – litb

    10. November 2008 um 8:04 Uhr

  • In diesem Snippet macht es wahrscheinlich keinen Unterschied, da das Ergebnis der Funktion niemals verwendet wird und die Funktion keine Seiteneffekte hat. Wir sehen einen messbaren Performance-Gewinn beim Inlining in der Bildverarbeitung.

    – Sockel

    2. März 2010 um 14:28 Uhr


  • Der Grund dafür, dass es keinen Unterschied gibt, könnte sein, dass der Compiler möglicherweise von sich aus einbettet; oder dass der Code klein ist, sodass es keine Probleme mit dem Codevorabruf gibt.

    – einpoklum

    19. Dezember 2015 um 16:15 Uhr

  • @einpoklum Der Compiler hat möglicherweise sogar die gesamte Schleife aus diesem Grund optimiert.

    – noɥʇʎʀʎzɐɹƆ

    13. Juni 2016 um 16:51 Uhr

In archaischem C und C++, inline ist wie register: ein Vorschlag (nichts weiter als ein Vorschlag) an den Compiler über eine mögliche Optimierung.

In modernem C++ inline teilt dem Linker mit, dass, wenn mehrere Definitionen (nicht Deklarationen) in verschiedenen Übersetzungseinheiten gefunden werden, sie alle gleich sind und der Linker frei eine behalten und alle anderen verwerfen kann.

inline ist obligatorisch, wenn eine Funktion (egal wie komplex oder “linear”) in einer Header-Datei definiert ist, damit mehrere Quellen sie einschließen können, ohne dass der Linker einen Fehler “mehrere Definitionen” erhält.

Innerhalb einer Klasse definierte Mitgliedsfunktionen sind standardmäßig “inline”, ebenso wie Vorlagenfunktionen (im Gegensatz zu globalen Funktionen).

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

Beachten Sie die Einbeziehung von fileA.h in zwei .cpp-Dateien, was zu zwei Instanzen von führt afunc(). Der Linker wird einen davon verwerfen. Wenn nein inline angegeben ist, wird sich der Linker beschweren.

Inlining ist ein Vorschlag an den Compiler, den er ignorieren kann. Es ist ideal für kleine Code-Bits.

Wenn Ihre Funktion eingebettet ist, wird sie im Grunde dort in den Code eingefügt, wo der Funktionsaufruf an sie erfolgt, anstatt tatsächlich eine separate Funktion aufzurufen. Dies kann bei der Geschwindigkeit helfen, da Sie nicht den eigentlichen Anruf tätigen müssen.

Es unterstützt auch CPUs beim Pipelining, da sie die Pipeline nicht mit neuen Anweisungen, die durch einen Aufruf verursacht werden, neu laden müssen.

Der einzige Nachteil ist eine mögliche erhöhte Binärgröße, aber solange die Funktionen klein sind, spielt dies keine große Rolle.

Ich neige dazu, diese Art von Entscheidungen heutzutage den Compilern zu überlassen (na ja, den schlauen sowieso). Die Leute, die sie geschrieben haben, verfügen in der Regel über weitaus detailliertere Kenntnisse der zugrunde liegenden Architekturen.

Die Inline-Funktion ist die von den Compilern verwendete Optimierungstechnik. Man kann dem Funktionsprototypen einfach ein Inline-Schlüsselwort voranstellen, um eine Funktion inline zu machen. Inline-Funktion weist den Compiler an, den vollständigen Text der Funktion dort einzufügen, wo diese Funktion im Code verwendet wurde.

Vorteile :-

  1. Es erfordert keinen Funktionsaufruf-Overhead.

  2. Es spart auch Overhead von Variablen Push/Pop auf dem Stack, während der Funktionsaufruf.

  3. Es spart auch den Overhead des Rückrufs einer Funktion.

  4. Es erhöht die Referenzlokalität durch Verwendung des Befehlscachespeichers.

  5. Nach dem Inlining kann der Compiler auch eine intraprozedurale Optimierung anwenden, falls angegeben. Dies ist die wichtigste, auf diese Weise kann sich der Compiler jetzt auf die Eliminierung von totem Code konzentrieren, kann mehr Gewicht auf die Verzweigungsvorhersage, die Eliminierung von Induktionsvariablen usw. legen.

Um mehr darüber zu erfahren, kann man diesem Link folgen
http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html

  • 1) Es ist ein Vorschlag, keine Anweisung. 2) Es kann aufgrund der Zunahme der Codegröße zu mehr Cache-Fehlern führen, wenn eine häufig verwendete Funktion häufig eingebunden wird

    – Flexo

    14. September 2011 um 18:09 Uhr

  • Ist der Link am Ende Ihr persönlicher Blog? Wenn ja, sollten Sie es als solches deklarieren, sonst sieht es nach Spam aus.

    – Flexo

    14. September 2011 um 18:10 Uhr

Ich möchte hinzufügen, dass Inline-Funktionen entscheidend sind, wenn Sie gemeinsam genutzte Bibliotheken erstellen. Ohne Markierungsfunktion inline wird es in binärer Form in die Bibliothek exportiert. Es ist auch in der Symboltabelle vorhanden, wenn es exportiert wird. Andererseits werden eingebettete Funktionen nicht exportiert, weder in die Binärdateien der Bibliothek noch in die Symboltabelle.

Es kann kritisch sein, wenn die Bibliothek zur Laufzeit geladen werden soll. Es kann auch binärkompatible Bibliotheken treffen. Verwenden Sie in solchen Fällen nicht Inline.

  • 1) Es ist ein Vorschlag, keine Anweisung. 2) Es kann aufgrund der Zunahme der Codegröße zu mehr Cache-Fehlern führen, wenn eine häufig verwendete Funktion häufig eingebunden wird

    – Flexo

    14. September 2011 um 18:09 Uhr

  • Ist der Link am Ende Ihr persönlicher Blog? Wenn ja, sollten Sie es als solches deklarieren, sonst sieht es nach Spam aus.

    – Flexo

    14. September 2011 um 18:10 Uhr

Während der Optimierung fügen viele Compiler Funktionen ein, auch wenn Sie sie nicht markiert haben. Sie müssen Funktionen im Allgemeinen nur dann als Inline markieren, wenn Sie etwas wissen, was der Compiler nicht weiß, da er normalerweise selbst die richtige Entscheidung treffen kann.

  • Viele Compiler werden dies auch nicht tun, MSVC zum Beispiel wird dies nicht tun, es sei denn, Sie sagen es

    – paulm

    2. Januar 2014 um 15:23 Uhr

993500cookie-checkVorteile von Inline-Funktionen in C++?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy