Когда использовать битовые ячейки STL вместо отдельных переменных?

В какой ситуации мне было бы более целесообразно использовать битовый набор (контейнер STL) для управления набором флагов, а не с их объявлением в виде нескольких отдельных переменных (bool)?

Получу ли я значительное увеличение производительности, если бы использовал битсет для 50 флагов, а не использовал 50 отдельных переменных bool?

Ответы

Ответ 1

Ну, 50 bools в качестве битового набора будут занимать 7 байт, а 50 bools, так как bools будут принимать 50 байт. В наши дни это не очень важно, поэтому использование bools, вероятно, прекрасное.

Однако одно место, которое может быть полезно для битов, - это то, что вам нужно много обходить эти bools, особенно если вам нужно вернуть набор из функции. С помощью битового набора у вас меньше данных, которые нужно переместить в стек для возврата. Опять же, вы могли бы просто использовать refs вместо этого и иметь еще меньше данных для прохождения.:)

Ответ 2

std:: bitset даст вам дополнительные очки, когда вам потребуется сериализовать/десериализовать его. Вы можете просто записать его в поток или прочитать из него поток. Но, разумеется, отдельные булы будут быстрее. Они оптимизированы для такого рода использования в конце концов, в то время как битрейт оптимизирован для пространства и имеет все еще функции вызовов. Это никогда не будет быстрее, чем отдельные bools.

BITSET

  • Очень эффективное пространство
  • Менее эффективно из-за бит-скриптов
  • Обеспечивает сериализацию/де-сериализацию с помощью op<< и op>>
  • Все биты упакованы вместе: у вас будут флаги в одном месте.

Отдельные bools

  • Очень быстро
  • Bools не упакованы вместе. Они будут членами где-то.

Решите факты. Я лично использовал бы std::bitset для некоторых критических некритичных и использовал бы bools, если бы у меня было только несколько bools (и, следовательно, это довольно обзорно), или если мне нужна дополнительная производительность.

Ответ 3

Это зависит от того, что вы подразумеваете под "приростом производительности". Если вам нужно только 50 из них, и вы невелики в памяти, тогда отдельные bools - это всегда лучший выбор, чем битсет. Они получат больше памяти, но bools будут намного быстрее. Битрейт обычно реализуется как массив ints (bools упаковываются в эти ints). Таким образом, первые 32 байта (бит) в вашем битете будут занимать только 32-битный int, но чтобы прочитать каждое значение, вам нужно сначала выполнить некоторые побитовые операции, чтобы замаскировать все значения, которые вы не хотите. Например. для чтения второго бита битового набора вам необходимо:

  • Найти int, содержащий бит, который вы хотите (в этом случае это первый int)
  • Побитовое И это int с '2' (то есть значение и 0x02), чтобы узнать, установлен ли этот бит

Однако, если память является узким местом, и у вас есть много bools с использованием битового набора, это может иметь смысл (например, если вы - целевая платформа - это мобильный телефон или это состояние в очень загруженном веб-сервисе)

ПРИМЕЧАНИЕ. std::vector bool обычно имеет специализацию для использования эквивалента битового набора, что делает его намного меньшим, а также медленнее по тем же причинам. Поэтому, если скорость является проблемой, вам будет лучше использовать вектор char (или даже int) или даже просто использовать старый массив bool школы.

Ответ 4

RE @Wilka:

На самом деле, биты поддерживаются 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 бит больше, чем данные, которые вы определяете (ее размер всегда минимальное количество байтов, необходимых для хранения данных, которые вы определили).