Inline -Expansion

Im Computer, Inline -Expansion, oder Einbindung, ist ein Handbuch oder Compiler -Optimierung Das ersetzt eine Funktion Rufseite mit dem Körper der genannten Funktion. Die Inline -Expansion ist ähnlich wie Makroerweiterung, aber tritt während der Kompilierung auf, ohne den Quellcode (den Text) zu ändern, während die Makroerweiterung vor der Kompilierung erfolgt, und führt zu einem unterschiedlichen Text, der dann vom Compiler verarbeitet wird.

Das Inline -Inline ist eine wichtige Optimierung, hat jedoch komplizierte Auswirkungen auf die Leistung.[1] Als ein Faustregel, einige Inline -Inlinen verbessern die Geschwindigkeit bei sehr geringfügigen Platzkosten, aber übermäßige Einbeziehung wird der Geschwindigkeit beeinträchtigen Befehlscacheund kosten auch erhebliche Platz. Eine Übersicht über die bescheidene akademische Literatur zur Einbeziehung der 1980er und 1990er Jahre ist in Peyton Jones & Marlow 1999 angegeben.[2]

Überblick

Die Inline -Expansion ähnelt der Makroerweiterung, da der Compiler eine neue Kopie der Funktion an jedem Ort platziert, den er aufgerufen wird. Inline-Funktionen werden etwas schneller ausgeführt als die normalen Funktionen, da Funktionen der Funktionen über die Köpfe gespeichert werden. Es gibt jedoch eine Speicherstrafe. Wenn eine Funktion 10 -mal eingegeben ist, werden 10 Kopien der Funktion in den Code eingefügt. Daher ist die Inlining für kleine Funktionen am besten, die oft als oft bezeichnet werden. In C ++ werden die Mitgliedsfunktionen einer Klasse standardmäßig eingebaut, wenn sie innerhalb der Klassendefinition definiert sind (keine Notwendigkeit, die zu verwenden in der Reihe Stichwort); Andernfalls wird das Schlüsselwort benötigt. Der Compiler kann den Versuch des Programmierers ignorieren, eine Funktion zu inline, hauptsächlich, wenn er besonders groß ist.

Die Inline -Expansion wird verwendet, um den Zeitaufwand (überschüssige Zeit) zu beseitigen, wenn eine Funktion aufgerufen wird. Es wird normalerweise für Funktionen verwendet, die häufig ausgeführt werden. Es hat auch einen Raumvorteil für sehr kleine Funktionen und ist eine Transformation für andere ermöglicht Optimierungen.

Ohne Inline -Funktionen, die Compiler entscheidet, welche inline funktioniert. Der Programmierer hat wenig oder gar keine Kontrolle darüber, welche Funktionen eingebaut sind und welche nicht. Wenn Sie dem Programmierer diesen Kontrollgrad geben, können Sie anwendungsspezifisch wissen, welche Funktionen inline sind.

Normalerweise, wenn eine Funktion aufgerufen wird, Kontrolle wird durch a auf seine Definition übertragen Zweig oder Anweisung anrufen. Durch die Inlining fällt die Steuerung direkt zum Code für die Funktion ohne Zweig oder Anrufbefehl.

Compiler Normalerweise implementieren Aussagen mit Inlining. Schleifenbedingungen und Schleifenkörper benötigen faule Bewertung. Diese Eigenschaft wird erfüllt, wenn der Code zum Berechnen von Schleifenbedingungen und Schleifenkörpern eingebaut ist. Leistungsüberlegungen sind ein weiterer Grund für Inline -Aussagen.

Im Zusammenhang mit Funktionale Programmiersprachen, Inline -Expansion folgt normalerweise von der Beta-Reduktion Transformation.

Ein Programmierer könnte eine Funktion manuell durchführen Programmieren kopieren und einfügen, als einmalige Operation auf der Quellcode. Andere Methoden zur Kontrolle des Inlins (siehe unten) sind jedoch vorzuziehen, da sie keine Fehler ausführen, die entstehen, wenn der Programmierer eine (möglicherweise modifizierte) doppelte Version des ursprünglichen Funktionsbehörde übersieht, während ein Fehler in der Ingineed -Funktion festgelegt wird.

Auswirkung auf die Leistung

Der direkte Effekt dieser Optimierung besteht darin, die Zeitleistung zu verbessern (durch Beseitigung von Call Overhead), auf Kosten der Verschlechterung der Raumnutzung[a] (wegen duplizieren der Funktionskörper). Die Code -Erweiterung aufgrund der Duplikation des Funktionskörpers dominiert mit Ausnahme einfacher Fälle.[b] und damit die direkte Wirkung der Inline -Expansion besteht darin, die Zeit auf Kosten des Raums zu verbessern.

Der Hauptvorteil der Inline -Expansion besteht jedoch darin, weitere Optimierungen und eine verbesserte Planung zu ermöglichen, da die Größe des Funktionskörpers erhöht wird, da eine bessere Optimierung bei größeren Funktionen möglich ist.[3] Der endgültige Einfluss der Inline -Expansion auf die Geschwindigkeit ist kompliziert, da mehrere Auswirkungen auf die Leistung des Speichersystems (hauptsächlich Befehlscache), die die Leistung für moderne Prozessoren dominiert: Abhängig vom spezifischen Programm und dem spezifischen Cache kann die Einbeziehung bestimmter Funktionen die Leistung erhöhen oder verringern.[1]

Die Auswirkungen des Inline -Inlines variieren je nach Programmiersprache und -programm aufgrund unterschiedlicher Abstraktionsgrade. In imperativen Sprachen unter niedrigerer Ebene wie C und FORTRAN ist es in der Regel ein Geschwindigkeitsschub von 10–20% mit geringfügigen Auswirkungen auf die Codegröße, während es in abstrakteren Sprachen aufgrund der Anzahl der Inline-Entfernungen von Schichten erheblich wichtiger sein kann. mit einem extremen Beispiel Selbst, wobei ein Compiler durch Inlining -Verbesserungsfaktoren von 4 bis 55 sah.[2]

Die direkten Vorteile der Beseitigung eines Funktionsaufrufs sind:

Der Hauptvorteil der Einbindung sind jedoch die weiteren Optimierungen, die es zulässt. Optimierungen, die die Funktionsgrenzen überschreiten Interprocedurale Optimierung (IPO): Sobald die Inlining durchgeführt wurde, wurde zusätzlich durchgeführt IntraVerfahrensoptimierungen ("globale Optimierungen") werden in der vergrößerten Funktionsbehörde möglich. Zum Beispiel:

  • A Konstante Als Argument bestanden kann häufig an alle Fälle des Matching -Parameters verbreitet werden, oder ein Teil der Funktion kann (über eine Schleife herausgehoben "werden (via Loop-Invariante-Codebewegung).
  • Zuteilung registrieren Kann über den größeren Funktionskörper hinweg erfolgen.
  • Hochrangige Optimierungen, wie z. Fluchtanalyse und die Schwanzverdoppelung kann mit einem größeren Bereich durchgeführt werden und effektiver sein, insbesondere wenn der Compiler, der diese Optimierungen implementiert, in erster Linie auf intra-procedurale Analysen stützt.[4]

Diese können ohne Einbindung erfolgen, erfordern jedoch einen wesentlich komplizierteren Compiler und Linker (falls Anrufer und Callee in separaten Kompilierungseinheiten befinden).

Umgekehrt kann in einigen Fällen eine Sprachspezifikation es einem Programm ermöglichen, zusätzliche Annahmen über Argumente für Verfahren zu treffen, die sie nach dem Eingebrauch des Verfahrens nicht mehr vornehmen können, wodurch einige Optimierungen verhindert werden können. Intelligentere Compiler (wie z. Glasgow Haskell Compiler) wird dies verfolgen, aber naive Einbrüche verliert diese Informationen.

Ein weiterer Vorteil der Einbeziehung des Speichersystems ist:

  • Beseitigung von Filialen und das Aufbewahren von Code, der im Speicher nahe beieinander ausgeführt wird Referenzort (räumliche Lokalität und Reihenfolge von Anweisungen). Dies ist kleiner als Optimierungen, die spezifisch auf Sequentialität abzielen, aber signifikant sind.[5]

Die direkten Kosten für die Einbrüche sind erhöhte Codegröße, da die Funktionsbehörde an jedem Anrufstandort dupliziert. Dies geschieht jedoch nicht immer, nämlich bei sehr kurzen Funktionen, bei denen der Funktionskörper kleiner ist als die Größe eines Funktionsaufrufs (beim Anrufer, einschließlich Argument- und Rückgabewertbehandlungen), wie z. B. trivial Accessor -Methoden oder Mutatormethoden (Getters und Setter); oder für eine Funktion, die nur an einem Ort verwendet wird, in diesem Fall wird sie nicht dupliziert. Daher kann das Inlining minimiert oder beseitigt werden, wenn sie die Codegröße optimieren, wie dies häufig der Fall ist eingebettete Systeme.

Das Inline -Inlin ist auch Kosten für die Leistung aufgrund der Code -Erweiterung (aufgrund von Duplikation) Verletzungsverletzungs -Cache -Leistung.[6] Dies ist am wichtigsten, wenn vor der Expansion die Workingset des Programms (oder eines heißen Codeabschnitts) passen in eine Ebene der Speicherhierarchie (z. B.,, L1 -Cache), aber nach der Expansion passt es nicht mehr, was zu häufigen Cache -Missen auf dieser Ebene führt. Aufgrund des signifikanten Leistungsunterschieds auf verschiedenen Ebenen der Hierarchie schadet dies die Leistung erheblich. Auf höchstem Niveau kann dies zu Erhöhungen führen Seitenfehler, katastrophaler Leistungsabbau aufgrund von Prügel, oder das Programm, das überhaupt nicht ausgeführt wird. Letzteres ist selten in gemeinsamen Desktop- und Serveranwendungen, bei denen die Codegröße im Verhältnis zum verfügbaren Speicher klein ist, aber ein Problem für ressourcenbeschränkte Umgebungen wie eingebettete Systeme sein kann. Eine Möglichkeit, dieses Problem zu mildern, besteht darin, Funktionen in einen kleineren heißen Inline -Pfad aufzuteilen (Schneller Weg) und ein größerer kalter nicht-inline-Pfad (langsamer Weg).[6]

Das Einbinden von Verletzungsleistung ist in erster Linie ein Problem für große Funktionen, die an vielen Stellen verwendet werden, aber der Break-Even-Punkt, über den die Inlining die Leistung verringert Profilgesteuerte Optimierung.[7] Dies ist ein ähnliches Problem wie andere Code, die Optimierungen erweitern, wie z. Schlaufe abrollen, was auch die Anzahl der verarbeiteten Anweisungen verringert, die Leistung jedoch aufgrund einer schlechteren Cache -Leistung verringern kann.

Der genaue Effekt der Einbindung der Cache -Leistung ist kompliziert. Für kleine Cache -Größen (viel kleiner als der Arbeitssatz vor der Expansion) dominiert die erhöhte Sequenzialität und die Inlining verbessert die Cache -Leistung. Bei Cache -Größen in der Nähe des Arbeitssatzes, bei dem das Inlining den Arbeitssatz erweitert, so dass es nicht mehr in Cache passt, dominiert dies und die Cache -Leistung nimmt ab. Bei Cache -Größen, die größer als der Arbeitssatz sind, wirkt sich die Inlining vernachlässigbar auf die Cache -Leistung aus. Darüber hinaus können Änderungen des Cache -Designs, wie z. B. Lastw ", die Erhöhung der Cache -Misses ausgleichen.[8]

Compiler -Unterstützung

Compiler verwenden eine Vielzahl von Mechanismen, um zu entscheiden, welche Funktionsaufrufe eingeführt werden sollen. Diese können manuelle Hinweise von Programmierern für bestimmte Funktionen zusammen mit der Gesamtsteuerung über die Gesamtsteuerung umfassen Befehlszeilenoptionen. Die Inlining wird automatisch von vielen Compilern in vielen Sprachen erfolgen Richtlinientypischerweise verwenden ein Schlüsselwort oder Compiler -Richtlinie genannt in der Reihe. In der Regel weist dies nur darauf hin, dass das Inline -Inlining gewünscht wird, anstatt das Einbinden zu erfordern, wobei die Kraft des Hinweiss von Sprache und Compiler variiert.

Normalerweise behalten Compiler -Entwickler die oben genannten Leistungsprobleme im Auge und einbeziehen sich Heuristik In ihre Compiler, die wählen, welche Funktionen in den meisten Fällen die Leistung verbessern sollen, anstatt sie zu verschlimmern.

Implementierung

Einmal der Compiler hat beschlossen, eine bestimmte Funktion zu investieren, und es ist normalerweise einfach, den Inlining -Operation selbst auszuführen. Abhängig davon, ob der Compiler-Einbindungseinlagen in verschiedenen Sprachen über Code verfügt Zwischendarstellung (wie Abstrakte Syntaxbäume) oder eine Zwischendarstellung auf niedriger Ebene. In beiden Fällen berechnet der Compiler einfach das Argumentespeichert sie in Variablen, die den Argumenten der Funktion entsprechen, und fügt dann den Körper der Funktion an der Anrufstelle ein.

Linker kann auch Funktionsingining machen. Wenn ein Linker Funktionen inliniert, kann er Funktionen inline können, deren Quelle nicht verfügbar ist, z. B. Bibliotheksfunktionen (siehe Link-Zeit-Optimierung). EIN Laufzeitsystem kann auch die Inline -Funktion. Laufzeit Inlining kann dynamische Profilinginformationen verwenden, um bessere Entscheidungen darüber zu treffen, welche Funktionen wie in der Inline -Funktionen sind, wie in der Java Hotspot Compiler.[9]

Hier ist ein einfaches Beispiel für die Inline -Erweiterung, die "von Hand" auf der Quellebene in der durchgeführt wird C Programmiersprache:

int Pred(int x) {   wenn (x == 0)   Rückkehr 0;   anders   Rückkehr x - 1; } 

Vor dem Inline:

int Func(int y)  {   Rückkehr Pred(y) + Pred(0) + Pred(y+1); } 

Nach dem Inlining:

int Func(int y)  {   int TMP;   wenn (y  == 0) TMP  = 0; anders TMP  = y - 1;  / * (1) */   wenn (0  == 0) TMP += 0; anders TMP += 0 - 1;  / * (2) */   wenn (y+1 == 0) TMP += 0; anders TMP += (y + 1) - 1; /* (3) */   Rückkehr TMP; } 

Beachten Sie, dass dies nur ein Beispiel ist. In einer tatsächlichen C -Anwendung wäre es vorzuziehen, eine Inlining -Sprachfunktion wie z. Parametrisierte Makros oder Inline -Funktionen um dem Compiler zu sagen, er solle den Code auf diese Weise transformieren. Im nächsten Abschnitt werden Möglichkeiten zur Optimierung dieses Codes aufgeführt.

Einbeziehung durch Montage -Makroerweiterung

Assembler -Makros Geben Sie einen alternativen Ansatz für das Inline -Ansatz an, bei dem normalerweise eine Folge von Anweisungen durch Makroerweiterung aus einer einzelnen Makro -Quellanweisung (mit null oder mehr Parametern) inline generiert werden kann. Einer der Parameter könnte eine Option sein, um alternativ ein einmaliges separates zu generieren Subroutine enthält die Sequenz und verarbeitet stattdessen durch einen eingefügten Aufruf in die Funktion. Beispiel:

Bewegen

Heuristik

Eine Reihe verschiedener Heuristiken wurde zum Einbinden untersucht. Normalerweise hat ein Inlining -Algorithmus ein bestimmtes Code -Budget (eine zulässige Erhöhung der Programmgröße) und zielt darauf ab, die wertvollsten Callsites zu investieren, ohne dieses Budget zu überschreiten. In diesem Sinne werden viele Inlining -Algorithmen normalerweise nach dem modelliert Rucksackproblem.[10] Um zu entscheiden, welche Callsites wertvoller sind, muss ein Inlining -Algorithmus ihren Vorteil abschätzen - d. H. Die erwartete Abnahme der Ausführungszeit. In der Regel verwenden Inliner Profilinginformationen über die Häufigkeit der Ausführung verschiedener Codepfade, um die Vorteile abzuschätzen.[11]

Neben der Profilerstellungsinformationen neuer Just-in-Time-Compiler Wenden Sie mehrere fortgeschrittene Heuristiken an, wie zum Beispiel:[4]

  • Das Spekulieren, welche Codepfade die Ausführungszeit am besten verkürzen (indem zusätzliche Compiler -Optimierungen infolge der Inlining ermöglicht werden) und den wahrgenommenen Nutzen solcher Pfade erhöhen.
  • Anpassungsmäßig die Leistungs-pro-Kosten-Schwelle für die Inline-Basis auf der Grundlage der Größe der Kompilierungseinheit und der bereits eingebrachten Codemenge einstellen.
  • Gruppieren von Unterprogrammen in Cluster und in der Einbeziehung ganzer Cluster anstelle von einzigartigen Unterprogrammen. Hier vermutet die heuristische Cluster, indem sie die Methoden gruppiert, für die das Einbinden nur eine ordnungsgemäße Teilmenge des Clusters zu einer schlechteren Leistung führt, als überhaupt nichts zu integrieren.

Vorteile

Die Inline -Expansion selbst ist eine Optimierung, da sie Overhead von Anrufen beseitigt, aber viel wichtiger ist als eine Transformation ermöglichen. Das heißt, sobald der Compiler eine Funktionskörper im Kontext seiner Anrufseite erweitert - oft mit Argumenten, die möglicherweise festgelegt werden Konstanten- Es kann möglicherweise eine Vielzahl von Transformationen durchführen, die vorher nicht möglich waren. Zum Beispiel a bedingter Zweig Kann sich auf dieser bestimmten Anrufe immer als wahr oder immer falsch herausstellen. Dies kann wiederum ermöglichen Dead Code Elimination, Loop-Invariante-Codebewegung, oder Induktionsvariable Eliminierung.

Im C -Beispiel im vorherigen Abschnitt gibt es viele Optimierungsmöglichkeiten. Der Compiler kann dieser Abfolge von Schritten folgen:

  • Das TMP += 0 Aussagen in den mit (2) und (3) markierten Zeilen tun nichts. Der Compiler kann sie entfernen.
  • Die Bedingung 0 == 0 ist immer wahr, sodass der Compiler die markierte Linie (2) durch das daraus resultierende ersetzen kann. TMP += 0 (was nichts tut).
  • Der Compiler kann den Zustand umschreiben y+1 == 0 zu y == -1.
  • Der Compiler kann den Ausdruck verringern (y + 1) - 1 zu y.
  • Die Ausdrücke y und y+1 kann nicht beide gleich Null sind. Dadurch können der Compiler einen Test beseitigen.
  • In Aussagen wie z. if (y == 0) return y der Wert von y ist im Körper bekannt und kann eingebaut werden.

Die neue Funktion sieht aus:

int Func(int y)  {   wenn (y == 0)   Rückkehr 0;   wenn (y == -1)   Rückkehr -2;   Rückkehr 2*y - 1; } 

Einschränkungen

Eine vollständige Inline -Erweiterung ist nicht immer möglich, weil Rekursion: rekursiv Inline -Erweiterung der Anrufe endet nicht. Es gibt verschiedene Lösungen, wie z. B. die Erweiterung eines begrenzten Betrags oder die Analyse des Rufen Sie Diagramm an und Brechen von Schleifen an bestimmten Knoten (d. H., Nicht etwas Rand in einer rekursiven Schleife auszudehnen).[12] Ein identisches Problem tritt bei der Makroausdehnung auf, da die rekursive Expansion nicht endet und typischerweise durch Verbot von rekursiven Makros (wie in C und C ++) aufgelöst wird.

Vergleich mit Makros

Traditionell in Sprachen wie z. C, Inline -Expansion wurde auf der Quellebene durchgeführt Parametrisierte Makros. Verwendung von echten Inline -Funktionen, wie in verfügbar C99bietet mehrere Vorteile gegenüber diesem Ansatz:

  • In C werden Makroaufrufe nicht durchgeführt Geben Sie die Überprüfung einoder sogar überprüfen, ob Argumente gut geformt sind, während Funktionsaufrufe normalerweise tun.
  • In C kann ein Makro das Schlüsselwort der Rückgabe nicht mit der gleichen Bedeutung wie eine Funktion verwenden (es würde die Funktion machen, die die Expansionsbeendigung anstelle des Makros gefragt hat). Mit anderen Worten, ein Makro kann nichts zurückgeben, was nicht das Ergebnis des letzten Ausdrucks ist.
  • Da C-Makros nur eine textliche Substitution verwenden, kann dies zu unbeabsichtigten Nebenwirkungen und Ineffizienz aufgrund der Neubewertung von Argumenten und zu Operationsreihenfolge.
  • Compiler -Fehler innerhalb von Makros sind oft schwer zu verstehen, da sie sich auf den erweiterten Code beziehen, anstatt den Code, den der Programmierer eingegeben hat. Daher ist das Debuggen von Informationen für eingelieferter Code normalerweise hilfreicher als der von Code mit Makro-Expandierten.
  • Viele Konstrukte sind unangenehm oder unmöglich, mit Makros auszudrücken oder eine signifikant unterschiedliche Syntax zu verwenden. Inline-Funktionen verwenden dieselbe Syntax wie gewöhnliche Funktionen und können mit Leichtigkeit nach Belieben eingebraucht und nicht eingedämmt werden.

Viele Compiler können auch einige erweitern rekursive Funktionen;[13] Rekursive Makros sind in der Regel illegal.

Bjarne StroustrupDer Designer von C ++ betont gern, dass Makros nach Möglichkeit vermieden werden sollten, und befürwortet eine umfassende Verwendung von Inline -Funktionen.

Auswahlmethoden

Viele Compiler -Inline -Funktionen, wo immer es dazu vorteilhaft ist, aggressiv. Obwohl es zu größerem führen kann AusführbareDas aggressive Inlining ist dennoch immer wünschenswerter, da die Gedächtniskapazität schneller zugenommen hat als die CPU -Geschwindigkeit. Die Einbrüche ist eine kritische Optimierung in Funktionssprachen und objektorientierte Programmiersprachen, die darauf angewiesen sind, dass es genügend Kontext für ihre typisch kleinen Funktionen bietet, um klassische Optimierungen wirksam zu machen.

Sprachunterstützung

Viele Sprachen, einschließlich Java und FunktionssprachenStellen Sie keine Sprachkonstrukte für Inline -Funktionen an, aber ihre Compiler oder Dolmetscher führen häufig eine aggressive Inline -Expansion durch.[4] Andere Sprachen bieten Konstrukte für explizite Hinweise, im Allgemeinen als Compiler Richtlinien (Pragmas).

In dem ADA -ProgrammierspracheEs gibt eine Pragma für Inline -Funktionen.

Funktionen in Common Lisp kann als Inline von der definiert werden in der Reihe Erklärung als solche:[14]

 (deklamieren (in der Reihe versenden))  (Defun versenden (x)  (Funcall  (erhalten (Wagen x) 'versenden) x)) 

Das Haskell Compiler GHC Versucht, Funktionen oder Werte zu inline, die klein genug sind, aber das Inline -Inlining kann ausdrücklich mit einem Sprachpragma festgestellt werden:[15]

Schlüsselfunktion :: Int -> Saite -> (Bool, Doppelt) {- # Inline Key_Function #-} 

C und C ++

C und C ++ einen haben in der Reihe Schlüsselwort, das beide als Compiler -Richtlinie fungiert und diese Einbeziehung angibt gewünscht aber nicht erforderlich- und ändert auch die Sichtbarkeit und das Verknüpfungsverhalten. Die Sichtbarkeitsänderung ist erforderlich, damit die Funktion über die Standard -C -Toolchain eingebaut werden kann, wobei die Zusammenstellung einzelner Dateien (eher,, Übersetzungseinheiten) folgt von Verknüpfungen: Damit der Linker Funktionen in der Lage sein kann, müssen sie im Header angegeben und sichtbar) und markiert werden in der Reihe (Um Unklarheiten aus mehreren Definitionen zu vermeiden).

Siehe auch

Anmerkungen

  1. ^ Die Platznutzung ist "Anzahl der Anweisungen" und sowohl die Laufzeit -Space -Nutzung als auch die Binärdatei Größe.
  2. ^ Die Codegröße schrumpft tatsächlich für sehr kurze Funktionen, wobei der Anrufaufwand größer ist als der Körper der Funktion oder Einzelnutzungsfunktionen, bei denen keine Duplikation auftritt.

Verweise

  1. ^ a b Chen et al. 1993.
  2. ^ Chen et al. 1993, 3.4 Funktionsinline -Expansion, p. 14.
  3. ^ a b c [1] Prokopec et al., Ein optimierungsgetriebener inkrementeller Inline-Substitutionsalgorithmus für Just-in-Time-Compiler, CGO'19-Veröffentlichung über den im Graal-Compiler für das JVM verwendeten Inlineer
  4. ^ Chen et al. 1993, 3.4 Funktionsinline -Expansion, p. 19–20.
  5. ^ a b Benjamin Poulain (8. August 2013). "Ungewöhnlicher Geschwindigkeitsschub: Größe ist wichtig".
  6. ^ Siehe zum Beispiel die Adaptives Optimierungssystem Archiviert 2011-08-09 im Wayback -Maschine in dem Jikes RVM für Java.
  7. ^ Chen et al. 1993, 3.4 Funktionsinline -Expansion, p. 24–26.
  8. ^ [2] Beschreibung des im Graal JIT Compiler für Java verwendeten Inlineer
  9. ^ [3] Scheifler, eine Analyse der Inline -Substitution für eine strukturierte Programmiersprache
  10. ^ [4] Matthew Arnold, Stephen Fink, Vivek Sarkar und Peter F. Sweeney, eine vergleichende Studie über statische und profilbasierte Heuristiken zum Inlining
  11. ^ Peyton Jones & Marlow 1999, 4. Gewährleistung von Beendigung, S. 6–9.
  12. ^ Einbindung der Semantik für rekursive Unterprogramme"Von Henry G. Baker
  13. ^ Erklärung IN DER REIHE, Notinline Bei der Common Lisp hyperspec
  14. ^ 7.13.5.1. Inline Pragma Kapitel 7. GHC -Sprachmerkmale

Externe Links