std::vector<bool> specialisation performance issue

L

Lionel B

On my platform I find that the std::vector<bool> specialisation incurs a
significant performance hit in some circumstances (when compared, say, to
std::vector<int> programmed analagously). Is it possible to "spoof"
std::vector into implementing a "true" vector of bool rather than the
specialisation?

Say I do:

typedef bool boolreally;
std::vector<booleally> bvec;

do I still get the std::vector<bool> specialisation? (I suspect the answer
is "yes", but I'm not sure how typedef-ed types are interpreted as
template parameters).

I can (and currently do) use std::vector<int> at times, but I'd rather
not, when what I want really is "bool" rather than "int" (or anything else).

As I understand it, the justification for the std::vector<bool>
specialisation is to reduce the space overhead (possibly at the cost of
a time overhead). Personally I can't envisage many circumstances where one
mightn't use std::bitset rather than std::vector<bool> if space were
an issue... I thus find the specialisation somewhat vexing. Am I
misunderstanding something here?
 
O

Ondra Holub

Lionel B napsal:
On my platform I find that the std::vector<bool> specialisation incurs a
significant performance hit in some circumstances (when compared, say, to
std::vector<int> programmed analagously). Is it possible to "spoof"
std::vector into implementing a "true" vector of bool rather than the
specialisation?

Say I do:

typedef bool boolreally;
std::vector<booleally> bvec;

do I still get the std::vector<bool> specialisation? (I suspect the answer
is "yes", but I'm not sure how typedef-ed types are interpreted as
template parameters).

typedef'ed types are equivalent for template instantiation. You can
test it with following code:

#include <iostream>

template<typename T>
void Test()
{
std::cout << "Test<T>\n";
}

template<>
void Test<int>()
{
std::cout << "Test<int>\n";
}

int main(int argc, char* argv[])
{
typedef
int INT;

I can (and currently do) use std::vector<int> at times, but I'd rather
not, when what I want really is "bool" rather than "int" (or anything else).

As I understand it, the justification for the std::vector<bool>
specialisation is to reduce the space overhead (possibly at the cost of
a time overhead). Personally I can't envisage many circumstances where one
mightn't use std::bitset rather than std::vector<bool> if space were
an issue... I thus find the specialisation somewhat vexing. Am I
misunderstanding something here?

std::bitset has fixed size, std::vector<bool> not.
 
L

Lionel B

Lionel B napsal:
On my platform I find that the std::vector<bool> specialisation incurs a
significant performance hit in some circumstances (when compared, say, to
std::vector<int> programmed analagously). Is it possible to "spoof"
std::vector into implementing a "true" vector of bool rather than the
specialisation?

Say I do:

typedef bool boolreally;
std::vector<booleally> bvec;

do I still get the std::vector<bool> specialisation? (I suspect the answer
is "yes", but I'm not sure how typedef-ed types are interpreted as
template parameters).
typedef'ed types are equivalent for template instantiation. You can
test it with following code:

[snip]

Yup, thanks.
[snip]
As I understand it, the justification for the std::vector<bool>
specialisation is to reduce the space overhead (possibly at the cost of
a time overhead). Personally I can't envisage many circumstances where one
mightn't use std::bitset rather than std::vector<bool> if space were
an issue... I thus find the specialisation somewhat vexing. Am I
misunderstanding something here?

std::bitset has fixed size,

Oops, so it has.
std::vector<bool> not.

As it happens, I have just read an article suggesting that one way to spoof
std::vector<bool> is to provide an explicit allocator, in which case the
non-specialised std::vector<bool> will be used... maybe overkill in my
case.
 
M

Michiel.Salters

Lionel said:
On my platform I find that the std::vector<bool> specialisation incurs a
significant performance hit in some circumstances (when compared, say, to
std::vector<int> programmed analagously). Is it possible to "spoof"
std::vector into implementing a "true" vector of bool rather than the
specialisation?

struct Bool {
Bool(bool b) : b(b) { }
bool b;
operator bool() { return b; }
// etc...
};

Also try std::deque<bool>. It does hold bools.

HTH,
Michiel Salters
 
D

David Harmon

On Fri, 8 Dec 2006 13:24:16 +0000 (UTC) in comp.lang.c++, "Lionel B"
Is it possible to "spoof"
std::vector into implementing a "true" vector of bool rather than the
specialisation?

Good question. I would be inclined to try a vector<unsigned char> and
let default conversions take care of the rest.
 
L

Lionel B

On Fri, 8 Dec 2006 13:24:16 +0000 (UTC) in comp.lang.c++, "Lionel B"


Good question. I would be inclined to try a vector<unsigned char> and
let default conversions take care of the rest.

I have done something like that before but it makes me - probably
unjustifiably - nervous... I can never somehow convince myself that
the default conversions will always do the "right thing"; i.e. at
the very least behave exactly like bool in all comparisons and assignments
with, to and from real bools as well as with, to and from the spoofed
bool (never mind with, to and from all other integer types...). Can this be
guaranteed?
 
K

kwikius

Lionel said:
I have done something like that before but it makes me - probably
unjustifiably - nervous... I can never somehow convince myself that
the default conversions will always do the "right thing"; i.e. at
the very least behave exactly like bool in all comparisons and assignments
with, to and from real bools as well as with, to and from the spoofed
bool (never mind with, to and from all other integer types...). Can this be
guaranteed?

It probably doesnt help your code (if it needs to interact with old
code), but IMO bool would be better by far if it didnt have automatic
conversions from a large range of types. In fact it would be
interesting to try a bool UDT which didnt allow the conversions, except
by comparisons and so on. It may actually run faster than the original
code due to a reduction in the number of conversions and also may
clarify the code which again is good for speed. It would also solve
your problem ;-)

regards
Andy Little
 
P

P.J. Plauger

As it happens, I have just read an article suggesting that one way to
spoof
std::vector<bool> is to provide an explicit allocator, in which case the
non-specialised std::vector<bool> will be used... maybe overkill in my
case.

Bad article. vector<bool> is partially specialized on its allocator type.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
B

BobR

Lionel B wrote in message ...
[snip]
std::bitset has fixed size,

Oops, so it has.
std::vector<bool> not.

As it happens, I have just read an article suggesting that one way to spoof
std::vector<bool> is to provide an explicit allocator, in which case the
non-specialised std::vector<bool> will be used... maybe overkill in my
case.

Well, if you are willing to 'overkill' anyway:

bool bl(true);
std::vector< std::bitset<1> > VecBit( 7, 1 );
if( bl == VecBit.at(0)[0] ){
std::cout<<"VecBit.at(0)="<<VecBit.at(0)<<std::endl;
std::cout<<" ="<<std::boolalpha<<VecBit.at(0)[0]<<std::endl;
}
// out: VecBit.at(0)=1
// out: =true
<G>



[ seems I heard this was deprecated, I may be thinking of something else. ]
// Example (stl docs) // #include <vector>
std::bit_vector V(5);
V[0] = true;
V[1] = false;
V[2] = false;
V[3] = true;
V[4] = false;

for( std::bit_vector::iterator i(V.begin()); i < V.end(); ++i )
std::cout<<std::boolalpha<<(*i)<<std::endl;
/* - out -
true
false
false
true
false
*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top