views:

1282

answers:

4

In what situation would it be more appropriate for me to use a bitset (STL container) to manage a set of flags rather than having them declared as a number of separate (bool) variables?

Will I get a significant performance gain if I used a bitset for 50 flags rather than using 50 separate bool variables?

+5  A: 

Well, 50 bools as a bitset will take 7 bytes, while 50 bools as bools will take 50 bytes. These days that's not really a big deal, so using bools is probably fine.

However, one place a bitset might be useful is if you need to pass those bools around a lot, especially if you need to return the set from a function. Using a bitset you have less data that has to be moved around on the stack for returns. Then again, you could just use refs instead and have even less data to pass around. :)

Herms
+3  A: 

It depends what you mean by 'performance gain'. If you only need 50 of them, and you're not low on memory then separate bools is pretty much always a better choice than a bitset. They will take more memory, but the bools will be much faster. A bitset is usually implemented as an array of ints (the bools are packed into those ints). So the first 32 bools (bits) in your bitset will only take up a single 32bit int, but to read each value you have to do some bitwise operations first to mask out all the values you don't want. E.g. to read the 2nd bit of a bitset, you need to:

  1. Find the int that contains the bit you want (in this case, it's the first int)
  2. Bitwise And that int with '2' (i.e. value & 0x02) to find out if that bit is set

However, if memory is a bottleneck and you have a lot of bools using a bitset could make sense (e.g. if you're target platform is a mobile phone, or it's some state in a very busy web service)

NOTE: A std::vector of bool usually has a specialisation to use the equivalent of a bitset, thus making it much smaller and also slower for the same reasons. So if speed is an issue, you'll be better off using a vector of char (or even int), or even just use an old school bool array.

Wilka
+1  A: 

RE @Wilka:

Actually, bitsets are supported by C/C++ in a way that doesn't require you to do your own masking. I don't remember the exact syntax, but it's something like this:

struct MyBitset {
  bool firstOption:1;
  bool secondOption:1;
  bool thirdOption:1;
  int fourBitNumber:4;
};

You can reference any value in that struct by just using dot notation, and the right things will happen:

MyBitset bits;
bits.firstOption = true;
bits.fourBitNumber = 2;

if(bits.thirdOption) {
  // Whatever!
}

You can use arbitrary bit sizes for things. The resulting struct can be up to 7 bits larger than the data you define (its size is always the minimum number of bytes needed to store the data you defined).

Herms
+2  A: 

std::bitset will give you extra points when you need to serialize / deserialize it. You can just write it to a stream or read from a stream with it. But certainly, the separate bools are going to be faster. They are optimized for this kind of use after all, while a bitset is optimized for space, and has still function calls involved. It will never be faster than separate bools.

Bitset

  • Very space efficient
  • Less efficient due to bit fiddling
  • Provides serialize / de-serialize with op<< and op>>
  • All bits packed together: You will have the flags at one place.

Separate bools

  • Very fast
  • Bools are not packed together. They will be members somewhere.

Decide on the facts. I, personally, would use std::bitset for some not-performance critical, and would use bools if I either have only a few bools (and thus it's quite overview-able), or if I need the extra performance.

Johannes Schaub - litb
I'd add the ability to use bitwise or operator to combine sets of flags as a huge win for bitset.
Greg Rogers