Heim  >  Artikel  >  Backend-Entwicklung  >  Können Lambdas durch Compiler besser optimiert werden als einfache Funktionen?

Können Lambdas durch Compiler besser optimiert werden als einfache Funktionen?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-19 18:33:03204Durchsuche

Can Lambdas Be Optimized Better Than Plain Functions By Compilers?

Compiler-Optimierungen für Lambdas vs. einfache Funktionen

In seinem Buch „The C Standard Library (Second Edition)“ behauptet Nicolai Josuttis dass Lambdas vom Compiler besser optimiert werden können als einfache Funktionen. Dies mag kontraintuitiv erscheinen, da sowohl Lambdas als auch einfache Funktionen eingebunden werden können. Es gibt jedoch einen subtilen Unterschied zwischen den beiden, der bessere Optimierungen im Fall von Lambdas ermöglicht.

Der Unterschied: Funktionsobjekte vs. Funktionszeiger

Lambdas sind Funktionsobjekte, während einfache Funktionen im Wesentlichen Funktionszeiger sind. Bei der Übergabe eines Lambda an eine Funktionsvorlage wird eine neue Funktion speziell für dieses Objekt instanziiert. Dadurch kann der Compiler den Lambda-Aufruf einfach einbinden.

Im Gegensatz dazu führt die Übergabe einer einfachen Funktion an eine Funktionsvorlage dazu, dass ein Funktionszeiger übergeben wird. Compiler hatten in der Vergangenheit Probleme mit der Inlining-Aufrufe über Funktionszeiger. Obwohl sie theoretisch inline sein können, tritt dies nur auf, wenn die umgebende Funktion ebenfalls inline ist.

Ein Beispiel

Betrachten Sie die folgende Funktionsvorlage:

template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Aufruf mit einem Lambda:

int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });

Führt zu einer eindeutigen 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 kann den Operator() des Lambda identifizieren und ihn trivial inline aufrufen.

Aber wenn es mit einem Funktionszeiger aufgerufen wird:

map(begin(a), end(a), &multiply_by_two);

Die Instanziierung wird zu:

template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Hier referenziert f bei jedem Aufruf von Map unterschiedliche Funktionen und verhindert so das Compiler vor Inlining-Aufrufen schützen, es sei denn, Map selbst ist inline.

Fazit

Der einzigartige Typ von Lambdas als Funktionsobjekte ermöglicht es Compilern, spezifische Funktionsinstanziierungen zu erstellen und ihre Aufrufe nahtlos einzubinden. Diese verbesserte Optimierungsfähigkeit unterscheidet Lambdas von einfachen Funktionen und macht sie zu einer bevorzugten Wahl für die Verbesserung der Codeleistung und -effizienz.

Das obige ist der detaillierte Inhalt vonKönnen Lambdas durch Compiler besser optimiert werden als einfache Funktionen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn