Desde un punto de vista lógico (no técnico), no hay ventaja.
Cualquier código C / C ++ simple se puede incluir dentro de una "construcción de biblioteca" adecuada. Después de tal ajuste, la cuestión de "si esto es más ventajoso que eso" se convierte en una cuestión discutible.
Desde el punto de vista de la velocidad, C / C ++ debería permitir que la construcción de la biblioteca genere código que sea tan eficiente como el código simple que envuelve. Sin embargo, esto está sujeto a:
- Función en línea
- Comprobación en tiempo de compilación y eliminación de comprobaciones de tiempo de ejecución innecesarias
- Eliminación de código muerto
- Muchas otras optimizaciones de código ...
Usando este tipo de argumento no técnico, cualquier "función faltante" podría ser agregada por cualquier persona y, por lo tanto, no se considera una desventaja.
Sin embargo, los requisitos y limitaciones incorporados no se pueden superar con código adicional. A continuación, sostengo que el tamaño de std::bitset
es una constante de tiempo de compilación y, por lo tanto, si bien no se considera una desventaja, sigue siendo algo que afecta la elección del usuario.
Desde un punto de vista estético (legibilidad, facilidad de mantenimiento, etc.), hay una diferencia.
Sin embargo, no es aparente que el std::bitset
código inmediatamente gane sobre el código C simple. Uno tiene que mirar piezas de código más grandes (y no una muestra de juguete) para decir si el uso de std::bitset
ha mejorado la calidad humana del código fuente.
La velocidad de la manipulación de bits depende del estilo de codificación. El estilo de codificación afecta tanto a la manipulación de bits C / C ++, y también es igualmente aplicable std::bitset
, como se explica a continuación.
Si uno escribe código que usa el operator []
para leer y escribir un bit a la vez, tendrá que hacerlo varias veces si hay más de un bit para manipular. Lo mismo puede decirse del código de estilo C.
Sin embargo, bitset
también tiene otros operadores, como operator &=
, operator <<=
etc., que opera en todo el ancho del conjunto de bits. Debido a que la maquinaria subyacente a menudo puede operar en 32 bits, 64 bits y, a veces, 128 bits (con SIMD) a la vez (en el mismo número de ciclos de CPU), código diseñado para aprovechar tales operaciones de múltiples bits puede ser más rápido que el código de manipulación de bits "en bucle".
La idea general se llama SWAR (SIMD dentro de un registro) , y es un subtema bajo manipulaciones de bits.
Algunos proveedores de C ++ pueden implementar bitset
entre 64 bits y 128 bits con SIMD. Es posible que algunos proveedores no lo hagan (pero eventualmente lo harán). Si es necesario saber qué está haciendo la biblioteca del proveedor de C ++, la única forma es mirar el desmontaje.
En cuanto a si std::bitset
tiene limitaciones, puedo dar dos ejemplos.
- El tamaño de
std::bitset
debe ser conocido en tiempo de compilación. Para hacer una matriz de bits con un tamaño elegido dinámicamente, uno tendrá que usar std::vector<bool>
.
- La especificación actual de C ++ para
std::bitset
no proporciona una forma de extraer una porción consecutiva de N bits de una bitset
M mayor .
El primero es fundamental, lo que significa que para las personas que necesitan conjuntos de bits de tamaño dinámico, deben elegir otras opciones.
El segundo se puede superar, porque uno puede escribir algún tipo de adaptadores para realizar la tarea, incluso si el estándar bitset
no es extensible.
Existen ciertos tipos de operaciones SWAR avanzadas que no se proporcionan desde el primer momento std::bitset
. Uno podría leer sobre estas operaciones en este sitio web sobre permutaciones de bits . Como de costumbre, uno puede implementarlos por su cuenta, operando además std::bitset
.
En cuanto a la discusión sobre el rendimiento.
Una advertencia: mucha gente pregunta por qué (algo) de la biblioteca estándar es mucho más lento que un código simple de estilo C. No repetiría los requisitos previos de microbenchmarking aquí, pero solo tengo este consejo: asegúrese de comparar en el "modo de lanzamiento" (con optimizaciones habilitadas), y asegúrese de que el código no se elimine (eliminación de código muerto) o sea izada fuera de un bucle (movimiento de código invariante de bucle) .
Dado que, en general, no podemos decir si alguien (en Internet) estaba haciendo los microbenchmarks correctamente, la única forma en que podemos llegar a una conclusión confiable es hacer nuestros propios microbenchmarks, documentar los detalles y someterlos a revisión y crítica pública. No está de más rehacer microbenchmarks que otros han hecho antes.
std::bitset
se fija en tiempo de compilación. Ese es el único inconveniente paralizante que se me ocurre.