Ist es praktisch, STL in der C ++ - Entwicklung aufzugeben? [geschlossen]

19

Ich weiß, dass STL in einigen Bereichen (z. B. in der Spieleindustrie) nicht empfohlen wird. Meine Frage ist also: Ist es wirklich eine gute Praxis, STL in einigen Fällen nicht zu verwenden? Wenn ja, was sind die Hauptgründe dafür, die STL des modernen C ++ nicht zu verwenden?

CaptainJH
quelle
verwandte
frage
Einige meiner Kollegen argumentieren, dass der Iterator das Debuggen erschwert, da es manchmal nicht einfach ist, sich einzumischen, und dies galt auch für das Lambda. Wie ist Ihre Antwort?
CaptainJH
Informationen
Martin Ba,
Das scheint eine gute Frage zu sein. Vielleicht könnte jemand hinzufügen: "Warum sollte ein Projekt die STL nicht verwenden?"
Matthew James Briggs

Antworten:

25
  • Ich kann mir nur einen gültigen Grund vorstellen und es ist wirklich selten: Harte Echtzeit. Viele Dinge in der Standardbibliothek weisen Speicher intern zu, und dies ist für harte Echtzeitanwendungen nicht deterministisch genug, sodass sie vermieden werden müssen. Diese Anwendungen sind normalerweise recht einfach, obwohl ihre Entwicklung aufgrund der sehr strengen Überprüfung und Prüfung unverhältnismäßig viel Zeit in Anspruch nimmt.

  • Ich kann mir einen ungültigen, aber sehr häufigen Grund vorstellen: Entwickler, die die Komplexität der Berechnungen nicht verstehen, missbrauchen STL und geben dann der Bibliothek die Schuld.

    STL ist normalerweise zur Laufzeit schneller als C-Lösungen mit Callback-Zeigern oder polymorphismusbasierte Lösungen mit virtuellen Methoden ( siehe auch die Keynote von Bjarne Stroustrup ). Wenn der Entwickler jedoch die angegebenen Komplexitätsspezifikationen nicht versteht und die Bibliothek missbraucht, indem er so etwas wie einen Vektor von Vektoren einiger komplexer Objekte erstellt (in C ++ 11 ist dies jedoch kein Problem mehr!), Kann er ein Leistungsproblem verursachen und sich dann selbst verteidigen "Sie sehen, die Vektoren sind ziemlich langsam" kann die Wahrnehmung hervorrufen, dass die Standardbibliothek langsam ist. Und sobald Manager eine solche Wahrnehmung haben, kann sie sehr lange in der Organisation leben.

  • Offensichtlich können Sie nichts verwenden, was die Plattform, auf die Sie abzielen, nicht unterstützt. Wir haben jedoch derzeit vier gängige mobile Plattformen im Visier (Android, iOS, Bada und altes WinCE) und verwenden die Standardbibliothek und einige Teile von Boost auf allen .

    Ein Großteil der Standardbibliothek wurde von Microsoft zu Beginn von WinCE nicht unterstützt (IIRC-iostreams wurden nur mit Visual Studio 2005 veröffentlicht), STLport konnte jedoch verwendet werden lange vorher zu verwenden. Und normalerweise kann man damit alles kompilieren. Deshalb würde ich diesen Grund auch als ungültig bezeichnen.

    Außerdem ist es lange nicht "STL", sondern ANSI C ++ Standard Library. Es wird durch dasselbe Standarddokument definiert, das die Sprache selbst definiert. Alles, was es nicht unterstützt, verdient es nicht, C ++ genannt zu werden.

Jan Hudec
quelle
6
Das erste Argument (Echtzeit) ist nicht spezifisch für die STL-Teile der Standardbibliothek. sprintfweist oft auch Speicher zu. Auf Echtzeitplattformen sind den Standardfunktionen der Bibliothek auch deterministische Grenzen gesetzt. Dies macht Echtzeit-C ++ - Implementierungen schwierig: Sie müssten sorgfältig eine ganze C ++ - Standardbibliothek entwickeln, was mehr Arbeit bedeutet als nur die kleine C-Standardbibliothek.
MSalters
@MSalters: Sicher, viele Dinge können unter Echtzeitanforderungen nicht verwendet werden. Sogar einige Sprachfunktionen wie Ausnahmen können dies nicht. Trotzdem ist C ++ eine großartige Sprache für diese Systeme, da es Leistung und präzise Steuerung mit starken Sicherheitsvorkehrungen verbinden kann (RAII ist dafür das wichtigste Merkmal).
Jan Hudec
@JanHudec: Aus diesem Grund werden die STL-Teile nur für "gehostete" Implementierungen von C ++ benötigt.
MSalters
7

Ich benutze STL und Boost schon seit vielen Jahren. Wenn ich es aufgeben und meine benutzerdefinierten Tools verwenden möchte, wäre die Motivation:

  1. Reduzierung der Kompilierzeit (75%). Allein durch das Einbeziehen von iostreams kann Ihr Modul um 1 Million Codezeilen erweitert werden. Ja, vorkompilierte Header helfen viel, aber sie verlangsamen die Kompilierung in großen Projekten immer noch sehr. Auf lange Sicht verschwendet es viel Zeit, wenn jemand daran arbeitet.
  2. Performance. (25%) STL ist so geschrieben, dass sie im Allgemeinen funktioniert. Sie können Ihre Strukturen jedoch so optimieren, dass sie genau so funktionieren, wie Sie es möchten. Beispielsweise könnten Sie Datenstrukturen mit Millionen von kurzen Zeichenfolgen haben. Die Verwendung einer benutzerdefinierten Zeichenfolgenklasse basierend auf dem Prinzip von boost :: small_vector (kleiner statischer lokaler Datenvektor, dynamische Zuweisung nur für größere Zeichenfolgen) ist möglicherweise viel schneller. Durch diese Art von Änderungen können wichtige Codeabschnitte um ein Vielfaches schneller ausgeführt werden.
Marwin
quelle
1
SSO ist bereits verbreitet.
Deduplicator
Für die Nachwelt: SSO -> Small-String-Optimierung, dh die meisten (alle?) std :: string-Implementierungen belassen kleine Strings auf dem Stack und wechseln bei Bedarf auf den Heap
blau
Kompilierzeiten sind groß
user1754322
4

Es gibt einen wichtigen Grund, die C ++ - Standardvorlagenbibliothek nicht zu verwenden: Eine Ihrer Zielplattformen verfügt nicht über eine vollständig konforme Implementierung (oder überhaupt keine Implementierung), und Sie wissen, dass es keine gibt innerhalb der nächsten Jahre.

Patrick
quelle
3
Aka "benutze es nicht, wenn du es nicht hast", was wirklich Sinn macht. :)
Xeo
4
Gibt es angesichts der Tatsache, dass die C ++ 03-Standardbibliothek nur für die ANSI C89-Bibliothek entwickelt wurde, eine Plattform, auf der Sie nicht mindestens STLPort erhalten konnten ?
Jan Hudec
@JanHudec Ich glaube, es gibt Plattformen ohne STL, weil sie nicht genug Speicher haben, um die ganze Sache zu handhaben. In der Regel fehlen ihnen auch andere C ++ - Funktionen (z. B. Ausnahmen).
Sulthan
2
@ Sulthan: Für Mikrocontroller verstehe ich das irgendwie, aber diese fallen normalerweise in die Kategorie "harte Echtzeit". Für alles andere sind dies meist Vorurteile, da STL in der Regel sowohl speicher- als auch leistungsmäßig genauso effizient ist wie handgefertigter Code. Viele Inlining-Vorgänge können zu größeren Binärdateien führen. Dies kann jedoch durch eine sorgfältige Implementierung mit einem gewissen Leistungsaufwand (der auch bei einer handgefertigten Lösung der Fall wäre) vermieden werden. Fehlende Ausnahmen sind entweder Vorurteile oder Faulheit, da die Definition und Implementierung der Ausnahmebedingung ABI aufwändig ist.
Jan Hudec
4

Ich kenne die Komplexität (Effizienz der Implementierung) nicht, aber ich verwende häufig Qt-Container und -Strings anstelle der Standard-Container und sie funktionieren einwandfrei. Ich finde auch die Qt-Implementierung von Mengen und Listen einfacher zu bedienen.

Es kann daher praktisch sein, die STL zu verlassen, wenn Sie eine andere Bibliothek verwenden können, die Ihren Anforderungen entspricht.

Giorgio
quelle
2
Die Qt-Äquivalente wurden vor langer Zeit erstellt, als es keine STL-Implementierungen gab, die entweder a) verfügbar oder b) gut waren. Das ist der einzige Grund, warum sie noch verwendet werden, nichts gegen die STL von heute.
gbjbaanb
1
@ Giorgio: Das Problem liegt in komplexen Anwendungen, in denen Sie mehrere Bibliotheken kombinieren. Die STL-Container bilden standardmäßig eine Verkehrssprache . Genauer gesagt, es sind ihre Konventionen, die das tun. Das bekannteste Beispiel ist Boost. Es kann an AWL-Containern arbeiten. es kann auch auf Qt - Containern arbeiten, aber nur , weil Qt hat folgende Konventionen STL - zBQList<T>::iterator
MSalters
3
Ich habe es nicht abgelehnt, aber ich sehe einen Grund: Es beantwortet die Frage nicht. Sie sagten, es gibt Dinge, die man anstelle von STL verwenden kann, aber das ist kein Grund, STL zu vermeiden. Abgesehen davon, dass es keinen Grund gibt, STL zu vermeiden, gilt dies wahrscheinlich auch für Qt, MFC und andere solche Bibliotheken oder noch mehr.
Jan Hudec
3
@NoOne: Wir wissen, dass Sie an Kamelgehäuse gewöhnt sind, nicht an Schlangengehäuse, aber das macht letzteres nicht schlimmer. Und von den drei von Ihnen kritisierten Funktionsnamen ist der erste perfekt für alle, die etwas mit C-Strings zu tun haben, und die beiden anderen, die von C geerbt wurden, werden diese nicht diskutieren.
Deduplizierer
1
@NoOne: Wie gesagt, ich verstehe total, dass Sie sich mit CamelCase wohler fühlen.
Deduplizierer
3

Patrick hat den Grund genannt, warum nicht die gesamte STL verwendet werden soll, und zwar, dass Ihre Plattform (en) keine Plattform (en) haben.

Alles in allem denke ich, dass die Frage den Punkt verfehlt. Es ist meistens keine Alles-oder-Nichts-Entscheidung, sondern eine Wahl. Möglicherweise entscheiden Sie sich für die Container und Algorithmen, entscheiden sich jedoch für die Verwendung von etwas außerhalb der Standardbibliothek für Zeichenfolgen und E / A.

Martin Ba
quelle
3

Es ist nicht praktikabel, es sei denn, es gibt einen schwerwiegenden Grund dafür. Einige dieser Gründe, die mir einfallen, sind die teilweise oder fehlende Implementierung von STL (oder eines anderen Teils der Standardbibliothek) oder eine Ressourcenbeschränkung (Speicher, CPU-Geschwindigkeit, Speicher, ...), die Sie umgehen müssen Rollen Sie Ihre eigenen Werkzeuge, die genau dem entsprechen, was Sie tun müssen.

In der Spielebranche haben die meisten (in gewissem Maße auch kleineren) Studios ihre internen Bibliotheken und Implementierungen vieler Standardbibliotheksteile, die in hohem Maße auf die Zielplattform und in einigen Fällen auf die Zielengine oder sogar das Spiel selbst zugeschnitten sind. Einfach ausgedrückt, wenn ein Spiel für Konsolen entwickelt wird, ist die Hardware nach heutigen Standards sehr begrenzt. Aus einem bestimmten Grund gibt es Tausende und Abertausende von handgefertigten Montagelinien. Es ist sehr wichtig, alle Arten von Ressourcen in Ihrem Code so gering wie möglich zu halten, damit das Spiel schneller läuft und mehr Inhalte in der Spielwelt (oder einer größeren Welt zum Beispiel) verfügbar sind, was hoffentlich zu einem besseren Produkt führt.

"Jedes erfolgreiche Spiel beginnt mit der Implementierung einer eigenen verknüpften Liste."

zxcdw
quelle
1
Ich kann mir vorstellen, dass jedes erfolgreiche Spiel mit dem Schreiben von Code mithilfe der Standardbibliothek beginnt und erst dann den Code optimiert, wenn das Spiel ein umfassendes Profil erstellt hat. Optimieren, bevor Sie Profildaten haben, die angeben, was optimiert werden muss, ist sinnlos.
Cromulent
Wahr. Der letzte Satz war nur ein Spiel auf die "alte" Art, Spiele in den frühen 90ern zu schreiben, als C ++ noch nicht so weit verbreitet war und Assembly + C der richtige Weg war. Vielleicht hätte ich es klarer machen sollen. Dies gilt jedoch auch für die Spielebranche in Konsolen. Die meisten Algorithmen und Datenstrukturen werden standardmäßig von Hand geschrieben, da jedes Byte und jeder Zyklus zählt (ja, auch auf Kosten der Wartbarkeit / Portabilität / was auch immer).
zxcdw
2
Es sollte gesagt werden, dass es eher eine alte Erfahrung ist, von der man lebt. Moderne Optimierer generieren in der Regel eine bessere Assemblierung aus einfachem wartbarem Code als der Programmierer von Hand, und die generischen Vorlagen wie in STL oder Boost sind oft inline, um so effizienten Code wie Spezialgehäuse alles von Hand zu erzeugen. Aber es gibt eine Menge Code, der in Zeiten begann, in denen das nicht der Fall war, und viele Leute, die das Handwerk gelernt haben und so weitermachen, obwohl es keinen Sinn mehr ergibt.
Jan Hudec
2
@JanHudec Die Sache ist, dass die Implementierungen (und auch das Verhalten) sehr genau auf die Aufgabe zugeschnitten sein müssen. Sie können hier und da einfach nicht ein paar Dutzend Bytes sparen (was die Referenzlokalität ruiniert), ein paar Zweige zur Validierung der Eingabe einbinden (Verzweigungsfehler und fehlende Cache-Anweisungen) und davon ausgehen, dass der Compiler weiß, wie Ihre Datenstrukturen vektorisiert werden Optimale Nutzung von SIMD (dies wird nicht der Fall sein, oder Sie müssen zumindest überprüfen, ob der Versuch korrekt ist). Natürlich ist das Schreiben von Echtzeitsoftware auf einem PC nicht so streng, Sie können immer eine schnellere CPU einsetzen. Nicht in Konsolen.
zxcdw