В какой ситуации для меня было бы более целесообразно использовать набор битов (контейнер STL) для управления набором флагов, а не объявлять их в виде нескольких отдельных (bool) переменных?
Получу ли я значительный выигрыш в производительности, если бы я использовал битовый набор для 50 флагов вместо 50 отдельных переменных bool?
Ну, 50 bools в качестве набора будет занимать 7 байтов, в то время как 50 bools в качестве bools займет 50 байтов. В наши дни это не имеет большого значения, поэтому использование bools, вероятно, хорошо.
Однако одно место, где набор битов может быть полезен, - это если вам нужно много раз передавать эти логические переменные, особенно если вам нужно вернуть набор из функции. Используя набор битов, вы получаете меньше данных, которые нужно перемещать в стеке для возврата. Опять же, вы можете просто использовать ссылки вместо этого и иметь еще меньше данных для передачи. :)
Это зависит от того, что вы подразумеваете под «повышением производительности». Если вам нужно только 50 из них, и у вас недостаточно памяти, тогда отдельные bools - это всегда лучший выбор, чем битовый набор. Они будут занимать больше памяти, но bools будет намного быстрее. Набор битов обычно реализуется в виде массива целых чисел (в эти целые числа упаковываются значения bool). Таким образом, первые 32 bools (биты) в вашем наборе битов займут только 32-битное целое, но для считывания каждого значения сначала нужно выполнить несколько побитовых операций, чтобы замаскировать все значения, которые вам не нужны. Например, чтобы прочитать 2-й бит набора, вам необходимо:
- Найдите int, который содержит бит, который вы хотите (в данном случае это первый int)
- Побитовое И это int с '2' (то есть значением & 0x02), чтобы узнать, установлен ли этот бит
Однако, если память является узким местом, и у вас много операций с использованием битов, это может иметь смысл (например, если ваша целевая платформа - мобильный телефон, или это состояние в очень загруженном веб-сервисе)
ПРИМЕЧАНИЕ: std :: vector из bool обычно имеет специализацию для использования эквивалента набора битов , что делает его намного меньше, а также медленнее по тем же причинам. Так что, если скорость является проблемой, вам лучше использовать вектор char (или даже int), или даже просто использовать массив старой школы bool.
RE @Wilka:
На самом деле, наборы битов поддерживаются C / C ++ таким образом, что вам не нужно делать свою собственную маскировку. Я не помню точный синтаксис, но это примерно так:
struct MyBitset {
bool firstOption:1;
bool secondOption:1;
bool thirdOption:1;
int fourBitNumber:4;
};
Вы можете ссылаться на любое значение в этой структуре, просто используя точечную нотацию, и правильные вещи произойдут:
MyBitset bits;
bits.firstOption = true;
bits.fourBitNumber = 2;
if(bits.thirdOption) {
// Whatever!
}
Вы можете использовать произвольные размеры бит для вещей. Результирующая структура может быть на 7 бит больше, чем данные, которые вы определяете (ее размер всегда равен минимальному количеству байтов, необходимых для хранения данных, которые вы определили).
std :: bitset даст вам дополнительные очки, когда вам нужно его сериализовать / десериализовать. Вы можете просто записать его в поток или прочитать из него. Но, конечно, отдельные bools будут быстрее. В конце концов, они оптимизированы для такого использования, в то время как набор битов оптимизирован для пространства и все еще включает вызовы функций. Это никогда не будет быстрее, чем отдельные bools.
BITSET
- Очень экономно
- Менее эффективен из-за мелочей
- Обеспечивает сериализацию / десериализацию с
op<<
иop>>
- Все биты упакованы вместе: флаги у вас будут в одном месте.
Отдельные bools
- Очень быстро
- Bools не упакованы вместе. Они будут где-то членами.
Определитесь с фактами. Лично я использовал бы std::bitset
для некоторых не критичных к производительности, и использовал бы bools, если у меня было бы только несколько bools (и, следовательно, это достаточно для обзора), или если мне нужна дополнительная производительность.