Inline-Ersetzung

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Die Inline-Ersetzung ist eine Optimierungsmethode von Compilern zur Steigerung der Ausführungsgeschwindigkeit eines Computerprogramms. Dabei wird der Code der aufzurufenden Funktion an Stelle des Aufrufs kopiert. Das reduziert den Mehraufwand für den Aufruf (Sichern der Register, Vorbereiten des Stacks), verbessert die Lokalität und weiterhin kann bei der Optimierung der Code beider Funktionen gemeinsam berücksichtigt werden.

Folgender Quelltext in C …

inline int quadrat(int x) {
   return x*x;
}

int c(int a, int b) {
   return quadrat(a) + quadrat(b);
}

… kann von Compiler so übersetzt werden, dass nicht die Funktion aufgerufen, sondern die Funktionsdefinition direkt eingefügt wird. Dieses Verhalten ist optional, weiterhin kann es auch ohne Angabe des Schlüsselwortes inline durch die Kürze der Funktion quadrat(…) ausgelöst werden. Das Gleiche kann mit der simplen Funktion c() selbst auch passieren, d. h. auch diese kann geinlined werden.

Weiterhin stellt das empfohlene Inlining keine Optimierung durch den Compiler, sondern eine durch den Programmierer dar.

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

Inline-Ersetzungen können in C teilweise die Funktion von Makros übernehmen, bieten aber zusätzlich die Sicherheit einer statischen Typprüfung wie bei Funktionen. Da diese mittlerweile häufig unerwünscht ist (generische Programmierung), formuliert man seit C++98 üblicherweise so:

template <class T>
T quadrat(T x) {
   return x*x;
}

template <class T>
T c(T a, T b) {
   return quadrat(a) + quadrat(b);
}

Sie muss explizit deklariert werden und kann für von Klassen unabhängige, wie auch für Elementfunktionen (Methoden) verwendet werden. In den Interna des Compilers sind Makros und Inline-Ersetzungen jedoch nicht zu vergleichen.

Es ist für den Compiler aber nicht für jede beliebig komplizierte Funktion möglich, die vom Programmierer gewünschte Ersetzung auch durchzuführen. Die Funktion muss nicht kompliziert sein, um sie nicht ersetzen zu können. Beispiel:

inline double fact(int x) {
   return x > 1 ? x*fact(x-1) : 1;
}

Dann wird der normale Funktionsaufruf beibehalten. Vielmehr ist das inline im Beispiel als Empfehlung an den Compiler zu sehen, der er aber nicht nachgehen muss. Speziell in C++ gibt es für Ausnahmefälle auch Compiler-spezifische stärkere Varianten von inline (wie z. B. __forceinline), deren Einsatz jedoch auf Kosten der Portabilität gehen kann. Ohne solche Varianten wird das Inline-Attribut jedoch von den meisten modernen Compilern zumindest bei hohen Optimierungsleveln ignoriert.

Manche Compiler können auch selbstständig für Inline-Ersetzung geeignete Funktionen in der Optimierungsphase identifizieren und ersetzen. In der Programmiersprache Eiffel etwa ist nur diese automatische Inline-Ersetzung vorgesehen.