std::vector: reserve required?

  • Thread starter Mike -- Email Ignored
  • Start date
A

anon

James said:
I get a core dump from g++ 4.2.1, when I compile with the usual
options. With or without the reserve() commented out. You
probably forgot the necessary options to make g++ usable. (One
of these days, someone will come out with a compiler which is
usable without special options. But it's not happened yet.)

Might be OT, but What options are you using for g++?

Yes and no. From experience, I find that undefined behavior
usually works in all of your tests, and then fails in the most
embarassing way possible in the demo before the most important
client.

"Whatever can go wrong will go wrong, and at the worst possible time, in
the worst possible way"
 
J

Jim Langston

Yannick Tremblay said:
No. It is unspecified behavior either way. reserve will allocate memory
to
extend the size of an array, but it does not actually grow the size.
resize() will both allocate the memory and extend the size also.

Note, that changing vec[jj] = jj;
to vec.push_back( jj );
would mean you don't need resize or reserve. However, if you know before
hand how much memory you are going to need, how many elements, you may
wish
to resize it to avoid needless calls to new.

Hmm, I would frown on the gratuitous use of resize()

Yes, resize should only be used (in this code) if the vec[jj] syntax or
using the buffer directly. Using push_back() .reserve() should suffice.
OK but more important if en is large.

Yes and no, since "large" is an abstract value. The simple addition of
..reserve() can save quite a number of new's and copies, enough that using it
if you know the size can make a big difference, and I don't know of any case
where it would actually hurt. Since en here is a non constant variable we
can figure that the programmer doesn't know what size it will actually be
here but will be set on some arbitary information. And since the program
knows at this point how big the vector will need to be, we might possibly
save a lot of needless news and copies by using reserve.

Usually, in my cases anyway, when using vectors I don't know before hand how
big the vector is going to be and just let it grow as needed.

Premature optimization? Hard to say. It depends on how often this code is
going to be called, etc.. but, really, if you know somehow how big the
vector is going to be, why not tell the vector?
alternately:
vec.resize( en ); // Allocates memory and changes size
// And initialise all elements !
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;

Yes, you do avoid reallocating of the vector buffer however,
vec.resize() will default initialize all elements in the vector. This
is likely to be much more expensive than using reserve() or even what
you would have to pay for using push_back() directly without
pre-reserving anything.

The typical use of resize would be more:

// some C API that returns data:
// void c_foo( int * buffer , size_t bufferSize )

//C++ code:

std::vector<int> v;
v.resize(200);
// get data using the C API:
c_foo( &v[0], v.size() );
// now you can use the data in the vector

Personally, I get uncomfortable using vec[jj] = ... syntax without knowing
that the elements were already in the vector. Which is where resize would
come in with using this syntax. In my own programs I would use the first
version, the .reserve() and push_back(), but it's a matter of choice I
think.

I pretty much agree with all your comments, other that I would use
..reserve() any time I knew before hand how big the vector was going to be.
 
J

James Kanze

Jim Langston said:
No. It is unspecified behavior either way. reserve will
allocate memory to extend the size of an array, but it does
not actually grow the size. resize() will both allocate the
memory and extend the size also.
Note, that changing vec[jj] = jj;
to vec.push_back( jj );
would mean you don't need resize or reserve. However, if you
know before hand how much memory you are going to need, how
many elements, you may wish to resize it to avoid needless
calls to new.
Hmm, I would frown on the gratuitous use of resize()

If you're going to use [] on the elements afterwards, it's not
gratuitous:).
OK but more important if en is large.

For a sufficient definition of large. In practice, I've never
really found it to make a measurable difference. But then, I
don't construct vectors with millions of elements which are
expensive to copy. Which brings up the second point: it's more
important if the elements are expensive to copy.
// And initialise all elements !
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
Yes, you do avoid reallocating of the vector buffer however,
vec.resize() will default initialize all elements in the
vector. This is likely to be much more expensive than using
reserve() or even what you would have to pay for using
push_back() directly without pre-reserving anything.

That's what I would have thought, too. Measurements with
vector<int> and vector<double>, on the other hand, show the
resize version to be considerably faster. On a Sparc, at least:
I just reran a benchmark, and found the version with resize
faster on Sparc, but the version with push_back and reserve
faster on a PC under Linux (both compiled with g++, using the
same options: -std=c++98 -pedantic -ffor-scope -fno-gnu-keywords
-foperator-names -pipe -Wall -W -Wno-sign-compare
-Wno-deprecated -Wno-non-virtual-dtor -Wpointer-arith
-Wno-unused -Wno-switch -Wno-missing-braces -Wno-long-long
-static-libgcc -O3 -fomit-frame-pointer -finline-functions

I'd still use push_back in this case; it seems more idiomatic.
And at the first sign of a performance problem, I'd slip in a
reserve (although I certainly wouldn't bother with it until
there was a performance problem).
 

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,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top