Boost logo

Boost :

Subject: Re: [boost] [review] The review of Boost.DoubleEnded starts today: September 21 - September 30
From: Thorsten Ottosen (tottosen_at_[hidden])
Date: 2017-09-27 18:20:33


Den 26-09-2017 kl. 21:36 skrev Tim Song via Boost:
> On Tue, Sep 26, 2017 at 1:14 PM, Thorsten Ottosen via Boost

>> So it's easy to say something is hard and unsafe to use. But what about the
>> alternative?
>>
>
> The problem is that the new hard/unsafe parts isn't justified by any
> hard performance numbers. We are talking about adding functions that
> make it more likely for users to do things wrong, possibly in a manner
> that's completely well-defined but massively inefficient
> (inappropriate reserves). The benefit from it is skipping a branch
> that the predictor probably gets right most of the time. On its face,
> this doesn't appear to me to be a substantial enough benefit to
> justify the cost. It is of course quite possible that I'm
> underestimating the benefit, but if so I'd like to see actual numbers
> proving it.

No disagreement.

>>
>>> What's the motivating use case for the unsafe_uninitialized functions
>>> that can't handled by a non-invariant-violating design like
>>> default_init? The sole example in the documentation is a
>>> devector<char> whose content will be filled by recv later, which can
>>> be handled equally well.
>>
>>
>> Can you elaborate on what this design is exactly? Thanks.
>
> The same design used in boost::container. You take a tag type that
> indicates that the elements should be default-initialized rather than
> value-initialized. For trivially default constructible types, this
> means that no initialization is actually performed.

Ok. So it would only work with trivially default constructible types,
right? That is, if the type is not trivially default constructible, you
get double initialization.

In a serialization library you might rely on constructors that take an
archive object and initializes the object.

> Of course if the type isn't trivially default constructible, it would
> still call the constructor. The question is: how often do such cases
> actually arise?

Hard to say, but not often.

>>> I'm somewhat surprised that dropping the move_if_noexcept/strong
>>> exception safety dance doesn't seem to have been considered for a
>>> container that's supposed to be performance-oriented.
>>
>>
>> For which container operation are you thinking about?
>
> Anything that reallocates, really. Basically, unconditionally move
> during reallocation instead of move_if_noexcept, and if the move
> throws you only get basic exception safety.

Does Boost.Container do this? Would it not make generic code harder to
reason about?

>>
>>> The default growth policy is:
>>>
>>>> static size_type new_capacity(size_type capacity);
>>>> Returns: 4 times the old capacity or 16 if it's 0.
>>>
>>>
>>> Why those numbers? Were they arbitrarily chosen or based on some sort
>>> of benchmark? If so, what?

I think we might have thought about the case where the class is used as
a local buffer. There you may want to minimize reallocations and not
worry about excessive memory use because the memory is reclaimed soon
enough.

kind regards

Thorsten


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk