public:
inline int GetValue() const {
return m_nValue;
}
inline void SetValue(int nNewValue) {
this -> m_nValue = nNewValue;
}
In Learn C ++ sagten sie, dass es schneller laufen würde. Also dachte ich, es wäre großartig, es auf Getter und Setter anzuwenden. Aber vielleicht gibt es einige Nachteile?
c++
performance
inline
getter-setter
Martijn Courteaux
quelle
quelle
Antworten:
Ich inline nichts, bis mir ein Profiler ausdrücklich gesagt hat, dass kein Inlining zu einem Leistungsproblem führt.
Der C ++ - Compiler ist sehr intelligent und wird diese einfache Funktion mit ziemlicher Sicherheit automatisch für Sie einbinden. Und normalerweise ist es schlauer als Sie und kann viel besser bestimmen, was eingefügt werden soll oder nicht.
Ich würde es vermeiden, darüber nachzudenken, was ich tun soll oder nicht, und mich auf die Lösung konzentrieren. Das
inline
spätere Hinzufügen des Schlüsselworts (was keine Garantie für Inline-BTW ist) ist sehr einfach und potenzielle Stellen können mit einem Profiler leicht gefunden werden.quelle
Wenn Sie sie in die Definition schreiben, werden sie
inline
standardmäßig berücksichtigt .Dies bedeutet , dass sie (erscheinen sich typischerweise in mehreren Übersetzungseinheiten seit Klassendefinitionen) in mehreren Übersetzungseinheiten zugelassen werden, nicht , dass sie tatsächlich werden inlined.
quelle
inline
wenn sie in der Klassendefinition definiert sind, die fast nichts mit dem Compiler / Linker zu tun hat, der eine Funktion einfügt.Dies ist eine schlechte Vorgehensweise in öffentlichen APIs. Jede Änderung dieser Funktionen erfordert eine Neukompilierung aller Clients.
Im Allgemeinen zeigt Getter und Setter eine schlechte Abstraktion, tun Sie es nicht. Wenn Sie ständig zu den Rohdaten in einer anderen Klasse wechseln, müssen Sie wahrscheinlich Ihre Klassen neu anordnen, stattdessen überlegen, wie Sie die Daten innerhalb einer Klasse bearbeiten möchten, und geeignete Methoden dafür bereitstellen.
quelle
Negative Punkte:
Der Compiler kann Sie ignorieren.
Jede Änderung dieser Funktionen erfordert eine Neukompilierung aller Clients.
Ein guter Compiler wird ohnehin nicht inline Funktionen einbinden, wenn dies angemessen ist.
quelle
Ich möchte auch hinzufügen, dass es ziemlich irrelevant ist, ob diese inline sind oder nicht, es sei denn, Sie führen Millionen von Gets / Sets pro Frame durch. Es lohnt sich ehrlich gesagt nicht, den Schlaf zu verlieren.
Denken Sie auch daran, dass nur weil Sie das Wort "inline" vor Ihre Deklaration + Definition setzen, dies nicht bedeutet, dass der Compiler Ihren Code inline macht. Es werden verschiedene Heuristiken verwendet, um herauszufinden, ob dies sinnvoll ist. Dies ist häufig der klassische Kompromiss zwischen Geschwindigkeit und Größe. Es gibt jedoch das Brute-Force-Schlüsselwort '__forceinline' in VC ++ (ich bin mir nicht sicher, was es in GCC ist), das auf die ausgefallenen Heuristiken des Compilers stampft. Ich empfehle es wirklich überhaupt nicht und außerdem wird es wahrscheinlich falsch sein, wenn Sie einmal auf eine andere Architektur portiert haben.
Versuchen Sie, alle Funktionsdefinitionen in die Implementierungsdatei aufzunehmen und die reinen Deklarationen für die Header zu belassen (es sei denn, Sie sind natürlich eine Vorlagen-Metaprogrammierung (STL / BOOST / etc). In diesem Fall befindet sich so ziemlich alles in den Headern;))
Einer der klassischen Orte, an denen Leute gerne inline arbeiten (zumindest in Videospielen, von denen ich komme), sind mathematische Überschriften. Kreuz- / Punktprodukte, Vektorlängen, Matrixlöschung usw. werden häufig in der Kopfzeile platziert, was ich nur für unnötig halte. 9/10 macht es keinen Unterschied für die Leistung, und wenn Sie jemals eine enge Schleife durchführen müssen, z. B. ein großes Vektorarray durch eine Matrix transformieren, ist es wahrscheinlich besser, die Mathematik manuell inline durchzuführen oder sie sogar besser zu codieren plattformspezifischer Assembler.
Oh, und noch ein Punkt: Wenn Sie der Meinung sind, dass eine Klasse wirklich mehr Daten als Code enthalten muss, sollten Sie eine gute alte Struktur verwenden, die das OO-Gepäck der Abstraktion nicht mit sich bringt. Dafür ist sie da. :) :)
Tut mir leid, ich wollte nicht so viel weitermachen, aber ich denke, es hilft, reale Anwendungsfälle zu berücksichtigen und mich nicht zu sehr auf pedantische Compiler-Einstellungen einzulassen (vertrau mir, ich war dort;))
Viel Glück.
Shane
quelle
Indem Sie den Code in die Kopfzeile einfügen, legen Sie Ihre internen Klassenarbeiten offen. Kunden können dies sehen und Annahmen darüber treffen, wie Ihre Klasse funktioniert. Dies kann es schwieriger machen, Ihre Klasse später zu ändern, ohne den Clientcode zu beschädigen.
quelle
Der Code wird etwas länger kompiliert und Sie verlieren die Kapselung. Alles hängt von der Größe des Projekts und seiner Art ab. In den meisten Fällen ist es in Ordnung, sie inline zu machen, wenn sie keine komplexe Logik haben.
Übrigens können Sie überspringen,
inline
wenn Sie direkt in der Klassendefinition implementieren.quelle
Das Inline-Schlüsselwort ist in Ihrem Fall bedeutungslos
Der Compiler wird Ihre Funktion einbinden, wenn dies möglich und möglich ist, unabhängig vom Schlüsselwort.
Das Schlüsselwort inline wirkt sich auf das Verknüpfen und nicht auf das Inlining aus. Es ist ein bisschen verwirrend, aber lesen Sie es nach.
Befindet sich die Definition in einer anderen Kompilierungseinheit (im Grunde genommen Quelldatei nach Präprozessor) als der Aufruf, ist Inlining nur möglich, wenn die Optimierung des gesamten Projekts und die Generierung des Verbindungszeitcodes aktiviert sind. Durch Aktivieren wird die Verknüpfungszeit erheblich verlängert (da praktisch alles im Linker neu kompiliert wird), die Leistung kann jedoch offensichtlich verbessert werden. Nicht sicher, ob es in GCC und VS standardmäßig aktiviert oder deaktiviert ist.
quelle
Ich würde sagen, dass Sie sich nicht darum kümmern müssen. Lesen Sie den FAQ-Abschnitt zum Inlining .
quelle
Keine Notwendigkeit, vertrauen Sie den Compilern, zumindest für solche Optimierungen!
"Aber nicht immer"
quelle
Ich muss sagen, ich habe nicht die starke Abneigung gegen diese Praxis, die andere in diesem Thread zu haben scheinen. Ich stimme zu, dass der Leistungsgewinn durch Inlining in allen außer den am häufigsten verwendeten Fällen vernachlässigbar ist. (Und ja, ich bin in der Praxis auf solche Fälle gestoßen.) Wenn ich diese Art von Inlining mache, mache ich es aus Bequemlichkeitsgründen und im Allgemeinen nur für Einzeiler wie diesen. In den meisten meiner Anwendungsfälle ist die Notwendigkeit, eine Neukompilierung auf der Clientseite zu vermeiden, wenn ich sie jemals ändere, nicht so stark.
Ja, Sie können das löschen
inline
, wie dies durch die Platzierung der Implementierung impliziert wird.Ich bin auch ein wenig überrascht über die Vehemenz gegen Accessoren. Man kann kaum an einer Klasse in einer OO-Sprache niesen, ohne ein paar zu verlieren, und sie sind schließlich eine gültige Technik, um die Implementierung von der Schnittstelle zu abstrahieren. Es ist also ein bisschen masochistisch, sie als schlechte OO-Praxis zu bezeichnen. Es ist ein guter Rat, Accessoren nicht wahllos zu schreiben, aber ich rate Ihnen auch, sich nicht vom Eifer mitreißen zu lassen, sie auszurotten.
Nehmen Sie das, Puristen. :-)
quelle