On 17.03.2021 07:10, Juha Nieminen wrote:
> Bonita Montero <
Bonita....@gmail.com> wrote:
>> Some time I wrote a class called gvector<> which derived from vector<>
>> and which grows the capacity of the vector by a constant value or a
>> constant factor, whichever is greater, usually startoing at the con-
>> stant value and then beeing overtaken by the constant factor at a
>> certain size when the latter results in a larger capacity than the
>> constant offset.
>> Today someone in another forum told me, that some vector<>-impmemen-
>> tations grow the capacity in powers of two. I couldn't believe that
>> because it appeared to me as too much bloat.
>
> Growing the capacity in powers of two simply means that the growth
> factor is 2.
>
> I haven't actually checked the math, but I believe that the factor
> of 2 is used because of the standard requirement that push_back()
> must be amortized-constant-time, and I think that doesn't work
> with any factor less than 2 (although, as said, I haven't checked
> the math).
With an initial size m and buffer increase factor C the work in copying
from old to new buffers is
1m + Cm + C²m + C³m ... + Cʳm = m(1 + C + C²m + C³m ... + Cʳm)
= m(Cʳ⁺¹-1)/(C-1)
where r, the number of buffer increases, is the floor of the C-logarithm
of current size n, so that Cʳ is O(n) regardless of the value of C.
A simple way to understand the formula (which I used to write it now) is
that e.g. 10³ - 1 = 999 = 9×(111) = 9×(10² + 10 + 1), so.
> It can be thought of like this: For each time a reallocation happens,
> which incurs an O(n) copying operation, you need an additional n
> O(1) operations to compensate (ie. keep the overall insertion time
> at O(1)). This can only work if the growth factor is 2.
It works for any growth factor ≥1, but the smaller it is the more time
is spent on buffer reallocations, and perhaps the more fragmented memory
becomes, while saving a bit on buffer size.
- Alf