Когда использовать битовые наборы STL вместо отдельных переменных? - PullRequest
13 голосов
/ 21 августа 2008

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

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

Ответы [ 4 ]

10 голосов
/ 21 августа 2008

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

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

9 голосов
/ 19 ноября 2008

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

BITSET

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

Отдельные bools

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

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

3 голосов
/ 21 августа 2008

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

3 голосов
/ 21 августа 2008

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

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

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

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

...