James Kanze
10/14/2008 9:34:00 AM
On Oct 14, 6:44 am, Stephen Horne <sh006d3...@blueyonder.co.uk> wrote:
> On Mon, 13 Oct 2008 23:08:12 -0400, Kai-Uwe Bux <jkherci...@gmx.net>
> wrote:
> >ab2...@gmail.com wrote:
> >> Does standard mandates that the reserve call should
> >> initialize a container's values to its defaults, hence
> >> vector<int> intVec; intVec.reserve(100) would make
> >> intVec[0]=intVec[1]....intVec[99]=0 ?
> >No. In fact, size() remains unchanged so that referencing
> >those elements is undefined behavior.
> Just to expand on that, reserve is for managing memory. If you
> know that you're about to add thousands of items to a vector,
> using a reserve to pre-grow the memory allocation can make it
> more efficient, since the memory allocation only gets grown
> once - not potentially dozens or hundreds of times.
It's rarely necessary for optimization reasons (although it
doesn't hurt). The main reason for using reserve() is to avoid
invalidating iterators, pointers and references into the vector.
(Appending to a vector will not invalidate iterators unless the
capacity() increases.) Another reason, particularly with very
large vectors, is to reduce total memory consumption.
> IIRC sequentially adding n items to the end of a vector takes
> O(n^2) time. This is because the memory gets grown O(n) times
> - every k items, say, where k is a constant - and each growing
> can involve copying the whole vector which is on average O(n)
> again.
The standard requires that appending to a vector be "amortized
constant time". In practice, this means that memory growth must
be exponential---older implementations generally doubled the
size each time, but I think the general consensus today is that
1.5 times is preferrable.
> If you can reserve the required space first, sequentially adding n
> items is O(n).
Creating a vector of n objects using push_back is required by
the standard to be O(n). All reserve() does is reduce the
constant factor.
> There is only one memory reallocation, and only one copying -
> at most - so its the actual appending of values that
> determines the time taken, not repeated memory reallocation
> and copying.
> There's also a scheme where the reserved memory is doubled on
> each reallocation, and this also gives O(n), though it's still
> slower than full preallocation.
The real problem with it is memory consumption. You can easily
end up consuming three times more memory than you are actually
using.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34