it-swarm.com.de

Sind reine Header-Bibliotheken effizienter?

Annahmen

  1. Einer der Vorteile von Nur-Header-Bibliotheken für C++ besteht darin, dass sie nicht separat kompiliert werden müssen.

  2. In C und C++ ist inline nur dann sinnvoll, wenn die Funktion definiert in einer Header-Datei * ist.

  3. Traditionell wurde in C das Layout .c/.h verwendet, wobei der Header die minimale öffentliche Schnittstelle der Übersetzungseinheit darstellt. In ähnlicher Weise ist .cpp/hpp.

Frage

Sind reine Header-Bibliotheken im Allgemeinen effizienter in Bezug auf Code und Ausführung als das herkömmliche Layout? Wenn ja, liegt dies an umfangreichen Inlining- oder anderen Optimierungen?

* - Das Definieren der Funktion in einem Header ermöglicht es dem Compiler, die Implementierung während der Kompilierung einer beliebigen Übersetzungseinheit zu sehen, und ermöglicht praktisch das Inlining von Code

51
Vorac

Einer der Vorteile von Nur-Header-Bibliotheken für C++ besteht darin, dass sie nicht separat kompiliert werden müssen

Nein, das ist kein Vorteil, ganz im Gegenteil - der Hauptteil der Bibliothek muss so oft kompiliert werden, wie er aufgenommen wird, nicht nur einmal. Dies verlängert normalerweise die Kompilierungszeiten. Wenn Sie sich jedoch auf die aufgeführten Vorteile beziehen hier in Wikipedia : In diesem Artikel geht es um einen geringeren Verwaltungsaufwand für den gesamten Erstellungs-, Verpackungs- und Bereitstellungsprozess.

In C und C++ ist Inline nur dann sinnvoll, wenn die Funktion in einer Header-Datei definiert ist *

Dies hängt vom Compiler/Linker-System ab, aber ich denke, dass dies für die meisten vorhandenen C- und C++ - Compiler zutrifft.

Traditionell wurde in C das Layout .c/.h verwendet, wobei der Header die minimale öffentliche Schnittstelle der Übersetzungseinheit darstellt. In ähnlicher Weise ist .cpp/hpp.

Das ist meistens richtig. C++ - Klassenheader enthalten häufig mehr als die minimale öffentliche Schnittstelle - sie enthalten normalerweise auch viele private Inhalte. Um dies zu mildern, werden Dinge wie das PIMPL-Idiom verwendet. Dies ist so etwas wie das "Gegenteil" einer Nur-Header-Bibliothek. Es wird versucht, den erforderlichen Header-Inhalt zu minimieren.

Aber um Ihre Hauptfrage zu beantworten: Dies ist ein Kompromiss. Je mehr Bibliothekscode in die Header-Dateien eingefügt wird, desto mehr hat der Compiler die Möglichkeit , den Code auf Geschwindigkeit zu optimieren (wenn dies wirklich passiert oder wenn Die Zunahme ist bemerkenswert, ist eine ganz andere Frage. Andererseits erhöht zu viel Code in den Headern die Kompilierungszeit. Insbesondere in großen C++ - Projekten kann dies zu einem ernsthaften Problem werden, siehe "Large Scale C++ Software Design" von John Lakos - obwohl das Buch etwas veraltet ist und einige der dort beschriebenen Probleme von angesprochen werden Moderne Compiler, die allgemeinen Ideen/Lösungen sind weiterhin gültig.

Insbesondere wenn Sie keine stabile Bibliothek (von Drittanbietern) verwenden, aber während Ihres Projekts Ihre eigenen Bibliotheken entwickeln, werden die Kompilierungszeiten offensichtlich. Jedes Mal, wenn Sie etwas in der Bibliothek ändern, müssen Sie eine Header-Datei ändern, wodurch alle abhängigen Einheiten neu kompiliert und verknüpft werden.

IMHO wird die Popularität von Nur-Header-Bibliotheken durch die Popularität der Template-Meta-Programmierung verursacht. Für die meisten Compiler sind Vorlagenbibliotheken muss Nur Header, da der Compiler den Hauptkompilierungsprozess nur starten kann, wenn die Typparameter angegeben sind, und für die vollständige Kompilierung und Optimierung muss der Compiler "beide bei" sehen einmal "- der Bibliothekscode plus die Werte der Vorlagenparameter. Das macht es unmöglich (oder zumindest schwierig), "vorkompilierte" Kompilierungseinheiten für eine solche Bibliothek zu erstellen.

48
Doc Brown

Lassen Sie uns zunächst einige Ihrer Annahmen zerstören:

  1. Einer der Vorteile von Nur-Header-Bibliotheken für C++ besteht darin, dass sie nicht separat kompiliert werden müssen.

Das separate Kompilieren von Dingen bedeutet möglicherweise, dass nicht alles neu kompiliert werden muss, wenn sich nur ein Teil ändert.
Also ein Nachteil statt ein Vorteil.

  1. In C und C++ ist Inline nur dann sinnvoll, wenn die Funktion in einer Header-Datei * definiert ist.

Ja, der einzige Effekt, den inline übrig hat, ist die Ausnahme von Ein-Definitions-Regel .
Wehe dir, wenn diese Definitionen in irgendeiner Weise unterschiedlich sind.

Wenn sich eine Funktion innerhalb einer Kompilierungseinheit befindet, markieren Sie sie als static. Dies macht auch Inlining wahrscheinlicher, da die Funktion verfügbar sein muss, um sie inline zu machen.
Schauen Sie sich dennoch die Optimierung der Verbindungszeit an, die mindestens von MSVC++, gcc und clang unterstützt wird.

  1. Traditionell wurde in C das Layout .c/.h verwendet, wobei der Header die minimale öffentliche Schnittstelle der Übersetzungseinheit darstellt. In ähnlicher Weise ist .cpp/hpp.

Nun, nur die minimale Benutzeroberfläche zu präsentieren, ist sicherlich eines der Ziele, eine höhere API- und ABI-Stabilität zu erreichen und die Kompilierungszeiten zu minimieren.

Insbesondere C++ - Klassen sind jedoch nicht wirklich darauf ausgerichtet, da alle privaten Bits in den Header gelangen, ebenso wie die geschützten, ob Sie daraus ableiten möchten oder nicht.

Das Entwurfsmuster PIMPL dient zum Reduzieren solcher Details.

Der Teil, in dem die Trennung von Schnittstelle und Implementierung in C++ vollständig fehlschlägt, sind jedoch Vorlagen.
Das Komitee hat versucht, etwas mit exportierte Vorlagen zu tun, aber das wurde als zu kompliziert aufgegeben und funktioniert nicht wirklich.

Jetzt arbeiten sie an einem richtigen Modulsystem , obwohl es langsam geht. Dies verkürzt die Kompilierungszeiten erheblich und sollte auch die API- und ABI-Stabilität erhöhen, indem ihre Oberfläche verringert wird.

Sind reine Header-Bibliotheken im Allgemeinen effizienter in Bezug auf Code und Ausführung als das herkömmliche Layout? Wenn ja, liegt dies an umfangreichen Inlining- oder anderen Optimierungen?

Nur-Header-Bibliotheken können hinsichtlich Codegröße und Ausführungszeit effizienter sein. Dies hängt jedoch davon ab, ob die Bibliothek gemeinsam genutzt wird, wie viel davon auf welche Weise verwendet wird und ob Inlining in diesem speziellen Fall einen entscheidenden Gewinn darstellt.

Und der Grund, warum Inlining für die Optimierung so wichtig ist, liegt nicht darin, dass das Inlining selbst einen so großen Schub darstellt, sondern darin, dass es sich ständig ausbreiten und weiter optimieren kann.

16
Deduplicator