Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Efficient way to store a limited number of booleans

Reply
Thread Tools

Efficient way to store a limited number of booleans

 
 
mathieu
Guest
Posts: n/a
 
      12-11-2007
Hi,

I was trying to make an entry in a std::map be stored more
efficiently. The struct contained 3 booleans discribing it's property,
so I am trying to make it as compact as possible.
Using a std::vector<bool> in this case does not work, or at least is
not as efficient for my particular case (size was 20 bytes). Same goes
for tr1::array<bool,3>.

Is there anything else that I could have reused ?

Here is the current code:

// Compact struct to store up to 8 booleans:
struct B3
{
template <unsigned int TPos>
void SetB(bool v) {
if( v ) b.b |= (0x80 >> TPos%;
else b.b &= (~(0x80 >> TPos%);
}
template <unsigned int TPos>
bool GetB() const {
return b.b & (0x80 >> (TPos%);
}
private:
union { unsigned char b; } b;
};

Thanks
-Mathieu
 
Reply With Quote
 
 
 
 
Pete Becker
Guest
Posts: n/a
 
      12-11-2007
On 2007-12-11 12:13:39 -0500, mathieu <> said:

>
> Is there anything else that I could have reused ?
>


Let the compiler do the work:

struct eight_bools
{
unsigned bool0 : 1;
unsigned bool1 : 1;
unsigned bool2 : 1;
unsigned bool3 : 1;
unsigned bool4 : 1;
unsigned bool5 : 1;
unsigned bool6 : 1;
unsigned bool7 : 1;
};

eight_bools data = { 0 };
data.bool6 = true;
data.bool6 = false;

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

 
Reply With Quote
 
 
 
 
mathieu
Guest
Posts: n/a
 
      12-11-2007
On Dec 11, 6:16 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2007-12-11 12:13:39 -0500, mathieu <mathieu.malate...@gmail.com> said:
>
>
>
> > Is there anything else that I could have reused ?

>
> Let the compiler do the work:
>
> struct eight_bools
> {
> unsigned bool0 : 1;
> unsigned bool1 : 1;
> unsigned bool2 : 1;
> unsigned bool3 : 1;
> unsigned bool4 : 1;
> unsigned bool5 : 1;
> unsigned bool6 : 1;
> unsigned bool7 : 1;
>
> };
>
> eight_bools data = { 0 };
> data.bool6 = true;
> data.bool6 = false;


s/unsigned/unsigned char/g

Much nicer/cleaner indeed !

Thanks
-Mathieu
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      12-11-2007
Pete Becker wrote:
> On 2007-12-11 12:13:39 -0500, mathieu <>
> said:
>>
>> Is there anything else that I could have reused ?
>>

>
> Let the compiler do the work:
>
> struct eight_bools
> {
> unsigned bool0 : 1;
> unsigned bool1 : 1;
> unsigned bool2 : 1;
> unsigned bool3 : 1;
> unsigned bool4 : 1;
> unsigned bool5 : 1;
> unsigned bool6 : 1;
> unsigned bool7 : 1;
> };
>
> eight_bools data = { 0 };
> data.bool6 = true;
> data.bool6 = false;


I am not sure about this, but I believe I've seen the compilers
that were making the object of any class type to have enough
padding to bring its size to divisible by some power of 2, and
it wasn't 1; it was more like 4. Not to say you can't control
it, of course...

What I'd probably do is to code a custom map which would do all
the 'map' thing but instead of storing an array of bool or even
a struct with bit fields, I'd make it store a char and when it
comes to manipulating that char, I'd have a proxy object that
can set and interrogate the respective bits in the stored char.

Whether it would constitute savings I am not sure, depends on
the implementation of 'map', I think.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      12-11-2007
mathieu wrote:
> On Dec 11, 6:16 pm, Pete Becker <p...@versatilecoding.com> wrote:
>> On 2007-12-11 12:13:39 -0500, mathieu <mathieu.malate...@gmail.com>
>> said:
>>
>>
>>
>>> Is there anything else that I could have reused ?

>>
>> Let the compiler do the work:
>>
>> struct eight_bools
>> {
>> unsigned bool0 : 1;
>> unsigned bool1 : 1;
>> unsigned bool2 : 1;
>> unsigned bool3 : 1;
>> unsigned bool4 : 1;
>> unsigned bool5 : 1;
>> unsigned bool6 : 1;
>> unsigned bool7 : 1;
>>
>> };
>>
>> eight_bools data = { 0 };
>> data.bool6 = true;
>> data.bool6 = false;

>
> s/unsigned/unsigned char/g


Does it make a real difference? I mean, did you check the
'sizeof' for the resulting struct?

> Much nicer/cleaner indeed !


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
mathieu
Guest
Posts: n/a
 
      12-11-2007
On Dec 11, 6:32 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> mathieu wrote:
> > On Dec 11, 6:16 pm, Pete Becker <p...@versatilecoding.com> wrote:
> >> On 2007-12-11 12:13:39 -0500, mathieu <mathieu.malate...@gmail.com>
> >> said:

>
> >>> Is there anything else that I could have reused ?

>
> >> Let the compiler do the work:

>
> >> struct eight_bools
> >> {
> >> unsigned bool0 : 1;
> >> unsigned bool1 : 1;
> >> unsigned bool2 : 1;
> >> unsigned bool3 : 1;
> >> unsigned bool4 : 1;
> >> unsigned bool5 : 1;
> >> unsigned bool6 : 1;
> >> unsigned bool7 : 1;

>
> >> };

>
> >> eight_bools data = { 0 };
> >> data.bool6 = true;
> >> data.bool6 = false;

>
> > s/unsigned/unsigned char/g

>
> Does it make a real difference? I mean, did you check the
> 'sizeof' for the resulting struct?


At least on gcc 4.1.2 (debian) it does. With unsigned int I get 4
(obviously) and with unsigned char I get 1 as expected (same size as
my solution but cleaner).


-Mathieu
 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      12-11-2007
On 2007-12-11 12:31:00 -0500, "Victor Bazarov" <> said:

> Pete Becker wrote:
>> On 2007-12-11 12:13:39 -0500, mathieu <>
>> said:
>>>
>>> Is there anything else that I could have reused ?
>>>

>>
>> Let the compiler do the work:
>>
>> struct eight_bools
>> {
>> unsigned bool0 : 1;
>> unsigned bool1 : 1;
>> unsigned bool2 : 1;
>> unsigned bool3 : 1;
>> unsigned bool4 : 1;
>> unsigned bool5 : 1;
>> unsigned bool6 : 1;
>> unsigned bool7 : 1;
>> };
>>
>> eight_bools data = { 0 };
>> data.bool6 = true;
>> data.bool6 = false;

>
> I am not sure about this, but I believe I've seen the compilers
> that were making the object of any class type to have enough
> padding to bring its size to divisible by some power of 2, and
> it wasn't 1; it was more like 4. Not to say you can't control
> it, of course...
>
> What I'd probably do is to code a custom map which would do all
> the 'map' thing but instead of storing an array of bool or even
> a struct with bit fields, I'd make it store a char and when it
> comes to manipulating that char, I'd have a proxy object that
> can set and interrogate the respective bits in the stored char.
>
> Whether it would constitute savings I am not sure, depends on
> the implementation of 'map', I think.
>


It also depends on the definition of "savings." It took less time to
write this code than it took to write the description of your version.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

 
Reply With Quote
 
mathieu
Guest
Posts: n/a
 
      12-11-2007
On Dec 11, 6:32 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> mathieu wrote:
> > On Dec 11, 6:16 pm, Pete Becker <p...@versatilecoding.com> wrote:
> >> On 2007-12-11 12:13:39 -0500, mathieu <mathieu.malate...@gmail.com>
> >> said:

>
> >>> Is there anything else that I could have reused ?

>
> >> Let the compiler do the work:

>
> >> struct eight_bools
> >> {
> >> unsigned bool0 : 1;
> >> unsigned bool1 : 1;
> >> unsigned bool2 : 1;
> >> unsigned bool3 : 1;
> >> unsigned bool4 : 1;
> >> unsigned bool5 : 1;
> >> unsigned bool6 : 1;
> >> unsigned bool7 : 1;

>
> >> };

>
> >> eight_bools data = { 0 };
> >> data.bool6 = true;
> >> data.bool6 = false;

>
> > s/unsigned/unsigned char/g

>
> Does it make a real difference? I mean, did you check the
> 'sizeof' for the resulting struct?


Actually you are raising a good point. Shouldn't I be doing:


struct eight_bools
{
bool bool0 : 1;
bool bool1 : 1;
bool bool2 : 1;
bool bool3 : 1;
bool bool4 : 1;
bool bool5 : 1;
bool bool6 : 1;
bool bool7 : 1;
};

Thanks
-Mathieu
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      12-11-2007
Pete Becker wrote:
> On 2007-12-11 12:31:00 -0500, "Victor Bazarov"
> <> said:
>> Pete Becker wrote:
>>> On 2007-12-11 12:13:39 -0500, mathieu <>
>>> said:
>>>>
>>>> Is there anything else that I could have reused ?
>>>>
>>>
>>> Let the compiler do the work:
>>>
>>> struct eight_bools
>>> {
>>> unsigned bool0 : 1;
>>> unsigned bool1 : 1;
>>> unsigned bool2 : 1;
>>> unsigned bool3 : 1;
>>> unsigned bool4 : 1;
>>> unsigned bool5 : 1;
>>> unsigned bool6 : 1;
>>> unsigned bool7 : 1;
>>> };
>>>
>>> eight_bools data = { 0 };
>>> data.bool6 = true;
>>> data.bool6 = false;

>>
>> I am not sure about this, but I believe I've seen the compilers
>> that were making the object of any class type to have enough
>> padding to bring its size to divisible by some power of 2, and
>> it wasn't 1; it was more like 4. Not to say you can't control
>> it, of course...
>>
>> What I'd probably do is to code a custom map which would do all
>> the 'map' thing but instead of storing an array of bool or even
>> a struct with bit fields, I'd make it store a char and when it
>> comes to manipulating that char, I'd have a proxy object that
>> can set and interrogate the respective bits in the stored char.
>>
>> Whether it would constitute savings I am not sure, depends on
>> the implementation of 'map', I think.
>>

>
> It also depends on the definition of "savings." It took less time to
> write this code than it took to write the description of your version.


Absolutely. It's sometimes faster to compare and swap all elements
in an array than to call 'std::sort' for it. And if we had some
specific definition of savings, we'd still be wearing animal skins
and living in caves...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Abhishek Padmanabh
Guest
Posts: n/a
 
      12-12-2007
On Dec 11, 10:13 pm, mathieu <mathieu.malate...@gmail.com> wrote:
> Hi,
>
> I was trying to make an entry in a std::map be stored more
> efficiently. The struct contained 3 booleans discribing it's property,
> so I am trying to make it as compact as possible.
> Using a std::vector<bool> in this case does not work, or at least is
> not as efficient for my particular case (size was 20 bytes). Same goes
> for tr1::array<bool,3>.
>
> Is there anything else that I could have reused ?
>
> Here is the current code:
>
> // Compact struct to store up to 8 booleans:
> struct B3
> {
> template <unsigned int TPos>
> void SetB(bool v) {
> if( v ) b.b |= (0x80 >> TPos%;
> else b.b &= (~(0x80 >> TPos%);
> }
> template <unsigned int TPos>
> bool GetB() const {
> return b.b & (0x80 >> (TPos%);
> }
> private:
> union { unsigned char b; } b;
> };


How about using std::bitset<3>?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Memory efficient way to store strings in hash maps using 朝の木 C++ 3 04-18-2012 09:37 AM
most efficient way to get number of files in a directory guba@vi-anec.de Perl Misc 9 01-04-2010 06:03 PM
limited connectivity for limited users =?Utf-8?B?aG9yc2VmbHk=?= Wireless Networking 1 03-24-2006 05:17 PM
array of booleans zeus2@hotmail.com Java 4 10-01-2005 05:29 PM
g++: integers as booleans, no warning? Martin Herbert Dietze C++ 9 02-18-2005 09:03 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57