Da un punto di vista logico (non tecnico), non vi è alcun vantaggio.
Qualsiasi semplice codice C / C ++ può essere inserito in un "costrutto di libreria" adatto. Dopo tale conclusione, la questione del "se questo sia più vantaggioso di così" diventa una questione controversa.
Da un punto di vista della velocità, C / C ++ dovrebbe consentire al costrutto di libreria di generare codice efficiente quanto il semplice codice che avvolge. Ciò è tuttavia soggetto a:
- Funzione in linea
- Controllo in fase di compilazione ed eliminazione di controlli di runtime non necessari
- Eliminazione del codice morto
- Molte altre ottimizzazioni del codice ...
Utilizzando questo tipo di argomento non tecnico, qualsiasi "funzione mancante" potrebbe essere aggiunta da chiunque, e quindi non viene considerata come uno svantaggio.
Tuttavia, i requisiti e le limitazioni integrati non possono essere superati con un codice aggiuntivo. Di seguito, sostengo che la dimensione di std::bitset
è una costante di tempo di compilazione, e quindi, sebbene non sia considerata uno svantaggio, è comunque qualcosa che influenza la scelta dell'utente.
Da un punto di vista estetico (leggibilità, facilità di manutenzione ecc.), C'è una differenza.
Tuttavia, non è evidente che il std::bitset
codice vince immediatamente sul semplice codice C. Bisogna guardare pezzi di codice più grandi (e non alcuni esempi di giocattoli) per dire se l'uso di std::bitset
ha migliorato la qualità umana del codice sorgente.
La velocità di manipolazione dei bit dipende dallo stile di codifica. Lo stile di codifica influenza sia la manipolazione dei bit C / C ++, sia ugualmente applicabile std::bitset
, come spiegato di seguito.
Se si scrive codice che utilizza il operator []
per leggere e scrivere un bit alla volta, sarà necessario farlo più volte se ci sono più bit da manipolare. Lo stesso si può dire del codice in stile C.
Tuttavia, bitset
ha anche altri operatori, come operator &=
, operator <<=
ecc, che opera su tutta la larghezza del bitset. Poiché i macchinari sottostanti possono spesso operare su 32 bit, 64 bit e talvolta 128 bit (con SIMD) alla volta (nello stesso numero di cicli della CPU), codice progettato per trarre vantaggio da tali operazioni multi-bit può essere più veloce del codice di manipolazione dei bit "loopy".
L'idea generale si chiama SWAR (SIMD all'interno di un registro) ed è un argomento secondario sotto manipolazioni di bit.
Alcuni fornitori di C ++ potrebbero implementare bitset
tra 64 e 128 bit con SIMD. Alcuni fornitori potrebbero non (ma potrebbero eventualmente farlo). Se è necessario sapere cosa sta facendo la libreria del fornitore C ++, l'unico modo è quello di esaminare lo smontaggio.
Per quanto riguarda se std::bitset
ha dei limiti, posso fare due esempi.
- La dimensione di
std::bitset
deve essere nota al momento della compilazione. Per creare una matrice di bit con dimensioni scelte dinamicamente, si dovrà usare std::vector<bool>
.
- L'attuale specifica C ++ per
std::bitset
non fornisce un modo per estrarre una porzione consecutiva di N bit da un maggiore bitset
di M bit.
Il primo è fondamentale, nel senso che per le persone che hanno bisogno di bitset di dimensioni dinamiche, devono scegliere altre opzioni.
Il secondo può essere superato, perché è possibile scrivere una sorta di adattatori per eseguire l'attività, anche se lo standard bitset
non è estensibile.
Esistono alcuni tipi di operazioni SWAR avanzate che non vengono fornite immediatamente std::bitset
. Si potrebbe leggere di queste operazioni su questo sito Web su permutazioni di bit . Come al solito, è possibile implementarli da soli, operando sopra std::bitset
.
Per quanto riguarda la discussione sulla performance.
Un'ammonizione: molte persone chiedono perché (qualcosa) dalla libreria standard è molto più lento di un semplice codice in stile C. Non vorrei ripetere la conoscenza dei prerequisiti del microbenchmarking qui, ma ho solo questo consiglio: assicurati di eseguire il benchmark in "modalità di rilascio" (con ottimizzazioni abilitate), e assicurati che il codice non venga eliminato (eliminazione del codice morto) o sollevato da un ciclo (movimento del codice invariante) .
Dato che in generale non possiamo dire se qualcuno (su Internet) stia eseguendo correttamente i microbenchmark, l'unico modo per ottenere una conclusione affidabile è quello di fare i nostri microbenchmark e documentare i dettagli e sottoporli a revisione pubblica e critica. Non fa male ri-fare microbenchmark che altri hanno già fatto.
std::bitset
è fissata in fase di compilazione. Questo è l'unico inconveniente paralizzante che mi viene in mente.