Aus logischer (nicht technischer) Sicht gibt es keinen Vorteil.
Jeder einfache C / C ++ - Code kann in ein geeignetes "Bibliothekskonstrukt" eingeschlossen werden. Nach einer solchen Umhüllung wird die Frage, ob dies vorteilhafter als das ist, zur strittigen Frage.
Unter dem Gesichtspunkt der Geschwindigkeit sollte C / C ++ es dem Bibliothekskonstrukt ermöglichen, Code zu generieren, der genauso effizient ist wie der einfache Code, den es umschließt. Dies unterliegt jedoch:
- Funktions-Inlining
- Überprüfung zur Kompilierungszeit und Vermeidung unnötiger Laufzeitüberprüfungen
- Beseitigung toter Codes
- Viele andere Code-Optimierungen ...
Mit dieser Art von nichttechnischem Argument können "fehlende Funktionen" von jedermann hinzugefügt werden und werden daher nicht als Nachteil gewertet.
Integrierte Anforderungen und Einschränkungen können jedoch nicht mit zusätzlichem Code überwunden werden. Im Folgenden wird argumentiert, dass die Größe von std::bitset
eine Konstante für die Kompilierungszeit ist. Daher wird sie zwar nicht als Nachteil gewertet, sie wirkt sich jedoch immer noch auf die Auswahl des Benutzers aus.
Unter ästhetischen Gesichtspunkten (Lesbarkeit, Wartungsfreundlichkeit usw.) gibt es einen Unterschied.
Es ist jedoch nicht ersichtlich, dass der std::bitset
Code den einfachen C-Code sofort gewinnt. Man muss sich größere Teile des Codes (und nicht irgendein Spielzeugbeispiel) ansehen, um festzustellen, ob die Verwendung von std::bitset
die menschliche Qualität des Quellcodes verbessert hat.
Die Geschwindigkeit der Bitmanipulation hängt vom Codierungsstil ab. Der Codierungsstil wirkt sich sowohl auf die C / C ++ - Bitmanipulation std::bitset
als auch auf diese aus, wie im Folgenden erläutert wird.
Wenn Sie Code operator []
schreiben, mit dem Sie jeweils ein Bit lesen und schreiben, müssen Sie dies mehrmals tun, wenn mehr als ein Bit bearbeitet werden muss. Gleiches gilt für den C-Code.
Allerdings bitset
hat auch andere Betreiber, wie operator &=
, operator <<=
etc., die auf der vollen Breite des bitset arbeitet. Da der zugrunde liegende Computer häufig mit 32-Bit-, 64-Bit- und manchmal mit 128-Bit-Code (mit SIMD) gleichzeitig (in der gleichen Anzahl von CPU-Zyklen) arbeiten kann, wurde Code entwickelt, um diese Multi-Bit-Vorgänge zu nutzen kann schneller sein als "schleifenförmiger" Bitmanipulationscode.
Die allgemeine Idee heißt SWAR (SIMD innerhalb eines Registers) und ist ein Unterthema unter Bitmanipulationen .
Einige C ++ - Anbieter implementieren möglicherweise bitset
zwischen 64-Bit und 128-Bit mit SIMD. Einige Anbieter tun dies möglicherweise nicht (aber möglicherweise auch). Wenn Sie wissen müssen, was die Bibliothek des C ++ - Herstellers tut, können Sie sich nur die Demontage ansehen.
Ob std::bitset
es Einschränkungen gibt, kann ich an zwei Beispielen erläutern.
- Die Größe von
std::bitset
muss zum Zeitpunkt der Kompilierung bekannt sein. Um ein Array von Bits mit dynamisch gewählter Größe zu erstellen, muss man verwenden std::vector<bool>
.
- Die aktuelle C ++ - Spezifikation für
std::bitset
bietet keine Möglichkeit zum Extrahieren eines aufeinanderfolgenden Schnitts von N Bits aus einem größeren bitset
von M Bits.
Der erste Punkt ist grundlegend, was bedeutet, dass Menschen, die dynamisch große Bitsets benötigen, andere Optionen wählen müssen.
Die zweite kann überwunden werden, weil man eine Art Adapter schreiben kann, um die Aufgabe auszuführen, selbst wenn der Standard bitset
nicht erweiterbar ist.
Es gibt bestimmte Arten von erweiterten SWAR-Operationen, die nicht ab Werk bereitgestellt werden std::bitset
. Über diese Operationen kann man auf dieser Website über Bit-Permutationen lesen . Diese kann man wie gewohnt selbstständig implementieren und aufbauen std::bitset
.
In Bezug auf die Diskussion über die Leistung.
Eine Warnung: Viele Leute fragen, warum (etwas) aus der Standardbibliothek viel langsamer ist als irgendein einfacher C-Code. Ich würde das vorausgesetzte Wissen über Mikrobenchmarking hier nicht wiederholen, aber ich habe nur den folgenden Rat: Stellen Sie sicher, dass Sie ein Benchmarking im "Release-Modus" durchführen (mit aktivierten Optimierungen) und dass der Code nicht beseitigt wird (Beseitigung toter Codes) oder nicht beseitigt wird aus einer Schleife gehisst (schleifeninvariante Codebewegung) .
Da wir im Allgemeinen nicht sagen können, ob jemand (im Internet) die Mikrobenchmarks richtig gemacht hat, können wir eine verlässliche Schlussfolgerung nur ziehen, indem wir unsere eigenen Mikrobenchmarks machen, die Details dokumentieren und der öffentlichen Überprüfung und Kritik unterziehen. Es tut nicht weh, Mikrobenchmarks zu wiederholen, die andere schon einmal gemacht haben.
std::bitset
wird zur Kompilierungszeit festgelegt. Das ist der einzige Nachteil, den ich mir vorstellen kann.