Z logicznego (nietechnicznego) punktu widzenia nie ma przewagi.
Każdy zwykły kod C / C ++ może być zawinięty w odpowiedni „konstrukt biblioteki”. Po takim opakowaniu kwestia „czy to jest bardziej korzystne niż to” staje się dyskusyjnym pytaniem.
Z punktu widzenia szybkości C / C ++ powinien umożliwiać konstruowaniu biblioteki generowanie kodu, który jest tak samo wydajny, jak zwykły kod, który pakuje. Jest to jednak uzależnione od:
- Inlining funkcji
- Sprawdzanie czasu kompilacji i eliminacja niepotrzebnego sprawdzania czasu wykonywania
- Eliminacja martwego kodu
- Wiele innych optymalizacji kodu ...
Używając tego rodzaju nietechnicznego argumentu, wszelkie „brakujące funkcje” mogą być dodawane przez każdego i dlatego nie są liczone jako wady.
Jednak wbudowanych wymagań i ograniczeń nie można obejść za pomocą dodatkowego kodu. Poniżej argumentuję, że rozmiar std::bitset
jest stałą czasową kompilacji, a zatem, chociaż nie jest liczony jako wada, wciąż jest to coś, co wpływa na wybór użytkownika.
Z estetycznego punktu widzenia (czytelność, łatwość konserwacji itp.) Istnieje różnica.
Jednak nie jest oczywiste, że std::bitset
kod natychmiast wygrywa nad zwykłym kodem C. Należy przyjrzeć się większym fragmentom kodu (a nie próbce zabawki), aby stwierdzić, czy użycie std::bitset
poprawiło ludzką jakość kodu źródłowego.
Szybkość manipulacji bitami zależy od stylu kodowania. Styl kodowania wpływa zarówno na manipulację bitami C / C ++, jak również ma zastosowanie std::bitset
, jak wyjaśniono poniżej.
Jeśli ktoś pisze kod, który używa operator []
do odczytu i zapisu jeden bit na raz, będzie musiał to zrobić wiele razy, jeśli będzie więcej niż jeden bit do manipulacji. To samo można powiedzieć o kodzie w stylu C.
Jednak bitset
ma też inne podmioty, takie jak operator &=
, operator <<=
itp, które działa na pełnej szerokości bitset. Ponieważ leżące u jego podstaw maszyny mogą często działać w trybie 32-bitowym, 64-bitowym, a czasem 128-bitowym (z SIMD) na raz (w tej samej liczbie cykli procesora), kod zaprojektowany jest tak, aby korzystać z takich operacji wielobitowych może być szybszy niż „pętlowy” kod manipulacji bitami.
Ogólna idea nazywa się SWAR (SIMD w rejestrze) i jest podtematem przy manipulowaniu bitami.
Niektórzy dostawcy C ++ mogą implementować bitset
SIMD między 64-bitami a 128-bitami. Niektórzy dostawcy mogą tego nie robić (ale mogą to zrobić). Jeśli trzeba wiedzieć, co robi biblioteka dostawcy C ++, jedynym sposobem jest przyjrzenie się dezasemblacji.
Jeśli chodzi o to, czy std::bitset
ma ograniczenia, mogę podać dwa przykłady.
- Rozmiar
std::bitset
musi być znany w czasie kompilacji. Aby stworzyć tablicę bitów o dynamicznie wybranym rozmiarze, trzeba będzie użyć std::vector<bool>
.
- Obecna specyfikacja C ++ dla
std::bitset
nie zapewnia sposobu wyodrębnienia kolejnego wycinka N bitów z większego bitset
z M bitów.
Pierwszy ma podstawowe znaczenie, co oznacza, że ludzie, którzy potrzebują dynamicznych zestawów bitów, muszą wybrać inne opcje.
Drugi można pokonać, ponieważ można napisać jakieś adaptery do wykonania zadania, nawet jeśli standard bitset
nie jest rozszerzalny.
Istnieją pewne typy zaawansowanych operacji SWAR, które nie są dostarczane od razu po wyjęciu z pudełka std::bitset
. Na tej stronie można przeczytać o tych operacjach dotyczących permutacji bitów . Jak zwykle można je wdrożyć samodzielnie, działając na zasadzie std::bitset
.
Odnośnie dyskusji na temat wydajności.
Jedno ostrzeżenie: wiele osób pyta, dlaczego (coś) ze standardowej biblioteki jest znacznie wolniejsze niż jakiś prosty kod w stylu C. Nie powtórzyłbym tutaj wstępnej wiedzy na temat znakowania mikrobenchowania, ale mam tylko następującą radę: upewnij się, że test porównawczy w „trybie zwolnienia” (z włączonymi optymalizacjami) i upewnij się, że kod nie jest eliminowany (eliminacja martwego kodu) lub nie jest wyciągnięty z pętli (niezmienny ruch kodu) .
Ponieważ generalnie nie jesteśmy w stanie stwierdzić, czy ktoś (w Internecie) prawidłowo robił znaki mikrodruku, jedynym sposobem na uzyskanie wiarygodnego wniosku jest zrobienie własnych znaków mikrodruku i udokumentowanie szczegółów oraz poddanie się publicznej ocenie i krytyce. Ponowne wykonywanie mikrodruków, które inni robili wcześniej, nie zaszkodzi.
std::bitset
jest ustalany w czasie kompilacji. To jedyna wada, o której myślę.