Heim >Backend-Entwicklung >C++ >Warum optimiert der Compiler Lambda-Funktionen effektiver als herkömmliche Funktionen?
Lambda-Optimierung und Inline-Funktionen: Der Vorteil des Compilers
Die Aussage von Nicolai Josuttis, dass Lambdas im Vergleich zu einfachen Funktionen eine überlegene Compileroptimierung aufweisen, hat viele fasziniert Entwickler. Bei der Untersuchung dieser Behauptung versuchen wir, die zugrunde liegenden Gründe für diesen Optimierungsvorteil aufzudecken.
Funktionsobjekte und Inlining
Lambdas, die Funktionsobjekte sind, haben einen entscheidenden Vorteil: Sie weiterzugeben Funktionsvorlagen lösen die Instanziierung einer maßgeschneiderten Funktion speziell für dieses Lambda aus. Dadurch kann der Compiler den Lambda-Aufruf mühelos einbinden.
Im Gegensatz dazu verwenden Funktionen Funktionszeiger, wenn sie an Funktionsvorlagen übergeben werden. Traditionell stoßen Compiler auf Herausforderungen beim Inlining von Aufrufen über Funktionszeiger. Eine Inline-Optimierung ist nur möglich, wenn die umschließende Funktion selbst inline ist.
Vorlageninstanziierungen: Den Unterschied erkunden
Um diese Ungleichheit zu veranschaulichen, betrachten Sie die Map-Funktionsvorlage:
template <typename Iter, typename F> void map(Iter begin, Iter end, F f) { for (; begin != end; ++begin) *begin = f(*begin); }
Aufrufen mit a lambda:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; });
führt zu einer benutzerdefinierten Instanziierung:
template <> void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) { for (; begin != end; ++begin) *begin = f.operator()(*begin); }
Der Compiler identifiziert die Funktion _some_lambda_type::operator() und kann sie direkt inline aufrufen. Jeder eindeutige Lambda-Typ führt zu einer neuen Instanziierung der Karte und garantiert so eine Lambda-spezifische Optimierung.
Im Gegensatz dazu führt der Aufruf von Karte mit einem Funktionszeiger zur folgenden Instanziierung:
template <> void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) { for (; begin != end; ++begin) *begin = f(*begin); }
Hier die Funktion Zeiger f zeigt bei jedem Kartenaufruf auf unterschiedliche Adressen, was eine Inline-Optimierung verhindert. Der Aufruf von „map“ muss inline erfolgen, damit der Compiler f in eine bestimmte Funktion auflösen kann.
Die Besonderheit von Lambdas als Funktionsobjekte und ihre Fähigkeit, Vorlageninstanziierungen zu erleichtern, ermöglichen Compilern daher größere Optimierungsmöglichkeiten als herkömmliche Funktionsaufrufe durch Zeiger.
Das obige ist der detaillierte Inhalt vonWarum optimiert der Compiler Lambda-Funktionen effektiver als herkömmliche Funktionen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!