Tuesday, March 26, 2019

Digest for comp.lang.c++@googlegroups.com - 25 updates in 3 topics

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 26 01:04AM +0100

On 25.03.2019 17:33, Öö Tiib wrote:
>> zero-initialization.
 
> The implied question (by parts of my answer that you erased) is why
> not to first reserve() and later emplace_back()?
 
Probably because the array is filled by someone else's C style API.
 
One can
 
* take the performance hit and copy the raw array used for the API, or
 
* make one's own little array wrapper to automate the lifetime
management, e.g. based on `unique_ptr`, and pass that around, or
 
* do a really hacky thing like defining an `int` wrapper as item type
for a `vector` and then reinterpreting the buffer pointers (hi ho hi ho,
off to that faraway land we go, oh oh oh).
 
 
Anyway I think it helps to define a span type to use for formal argument.
 
That way one can remove much of the dependency on a particular array
representation.
 
 
Cheers!,
 
- Alf
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 10:06AM +0100

>> zero-initialization.
 
> The implied question (by parts of my answer that you erased) is why
> not to first reserve() and later emplace_back()?
 
Because this isn't that efficient like growing the vecor in one
step with uninitialized values and then initializing the values.
"Öö Tiib" <ootiib@hot.ee>: Mar 26 06:23AM -0700

On Tuesday, 26 March 2019 11:06:09 UTC+2, Bonita Montero wrote:
> > not to first reserve() and later emplace_back()?
 
> Because this isn't that efficient like growing the vecor in one
> step with uninitialized values and then initializing the values.
 
Why? This is doing exactly that. The reserve() allocates
uninitialized buffer and emplace_back()s initialize values in it.
With what platform the difference in efficiency was measured?
It sounds pretty much like an issue of quality of implementation.
Paavo Helde <myfirstname@osa.pri.ee>: Mar 26 03:33PM +0200

On 26.03.2019 11:06, Bonita Montero wrote:
>> not to first reserve() and later emplace_back()?
 
> Because this isn't that efficient like growing the vecor in one
> step with uninitialized values and then initializing the values.
 
Note that reserve() + emplace_back() is exactly that: growing the vector
in one step with uninitialized values and then initializing the values.
 
It might indeed be that using raw allocation plus assignment would be
slightly faster. If the profiler really shows there is a problem, you
can just use array new as at this optimization level you cannot use most
of std::vector functionality anyway:
 
std::unique_ptr<int[]> buffer(new int[n]);
 
AFAIK this is the last use case for 'new' and even this will be replaced
in C++20 with:
 
auto buffer = std::make_unique_default_init<int[]>(n);
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 03:35PM +0100

> Why? This is doing exactly that. The reserve() allocates
> uninitialized buffer and emplace_back()s initialize values
> in it.
 
emplace_back increases the size for each enlargement.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 03:36PM +0100

> Note that reserve() + emplace_back() is exactly that: growing the vector
> in one step with uninitialized values and then initializing the values.
 
No, emplace_back increases the size of the container for each call
whereas the solution I'm thinking about increases the size in one
step.
Martijn van Buul <pino@dohd.org>: Mar 26 02:53PM

* Paavo Helde:
> std::unique_ptr<int[]> buffer(new int[n]);
 
> AFAIK this is the last use case for 'new'
 
... that you're willing to consider.
 
Please show me an implementation of any of the containers, or any of the
"smart" pointers that does not rely on 'new'.
 
--
Martijn van Buul - pino@dohd.org
leigh.v.johnston@googlemail.com: Mar 26 08:02AM -0700

On Tuesday, March 26, 2019 at 2:53:51 PM UTC, Martijn van Buul wrote:
 
> ... that you're willing to consider.
 
> Please show me an implementation of any of the containers, or any of the
> "smart" pointers that does not rely on 'new'.
 
Are you being deliberately obtuse? Obviously Paavo wasn't thinking about implementers of the Standard Library because, like, 0.0000001% of the programmer population are Standard Library implementers.
 
/Leigh
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 04:24PM +0100

>> AFAIK this is the last use case for 'new'
 
> Please show me an implementation of any of the containers,
> or any of the "smart" pointers that does not rely on 'new'.
 
The difference here is that the above solution doesn't initialize
the ints.
guinness.tony@gmail.com: Mar 26 08:52AM -0700

On Tuesday, 26 March 2019 14:35:34 UTC, Bonita Montero wrote:
> > uninitialized buffer and emplace_back()s initialize values
> > in it.
 
> emplace_back increases the size for each enlargement.
 
emplace_back() increases the /logical/ size (as reported by size()) of the
container for each emplacement. It only increases the /physical/ allocation
(as reported by capacity()) if size() == capacity().
 
By first using reserve(), you can increase the physical allocation (but not
the logical size), ready to accept a number of emplacements:
 
std::vector< int > container; // capacity() == 0, size() == 0
container.reserve( 3 ); // capacity() == 3, size() == 0
 
// no re-allocations will occur during the execution of the following lines:
 
container.emplace_back( 42 ); // capacity() == 3, size() == 1
container.emplace_back( 42 ); // capacity() == 3, size() == 2
container.emplace_back( 42 ); // capacity() == 3, size() == 3
 
// now size() == capacity(), so re-allocation will occur on the next line:
 
container.emplace_back( 42 ); // capacity() == 4 or more, size() == 4
jameskuyper@alumni.caltech.edu: Mar 26 08:58AM -0700

On Tuesday, March 26, 2019 at 10:36:50 AM UTC-4, Bonita Montero wrote:
 
> No, emplace_back increases the size of the container for each call
> whereas the solution I'm thinking about increases the size in one
> step.
 
True, but increasing the size isn't an expensive operation. It's
increasing the capacity that's expensive, and when you call reserve(),
it increases the capacity in a single step, which is what you really
should be concerned about.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 04:59PM +0100

>> emplace_back increases the size for each enlargement.
 
> emplace_back() increases the /logical/ size (as reported by size()) of the
> container for each emplacement.
 
I didn't say anything different. The term "size" here means the
logical aize because if you call .size(), you get the logical size.
 
The issue here is that the container either has a size-member internally
(rather unlikely) or a begin- and an end-pointer (very likely). The lat-
ter is usually adjustet for each emplace_back or push_back; that's not
very efficient compared to growing the size of the container with its
elements not initialized in one step.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 05:02PM +0100

>> whereas the solution I'm thinking about increases the size in one
>> step.
 
> True, but increasing the size isn't an expensive operation.
 
If you have a expensive initialization of the elemens increasing
the size puts not much weight on that. But if you have a cheap
initialization, growing the size might have an essential share.
Paavo Helde <myfirstname@osa.pri.ee>: Mar 26 06:32PM +0200

On 26.03.2019 16:53, Martijn van Buul wrote:
>> std::unique_ptr<int[]> buffer(new int[n]);
 
>> AFAIK this is the last use case for 'new'
 
> ... that you're willing to consider.
 
Yes, I should have clarified I meant application level programming.
 
 
> Please show me an implementation of any of the containers, or any of the
> "smart" pointers that does not rely on 'new'.
 
Indeed, containers may use 'new' a lot, but this would then be placement
new and not memory allocation. Memory is typically allocated through
special allocator classes.
 
Smartpointers don't allocate anything at all, they just encapsulate
already allocated objects.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 05:52PM +0100

> Please show me an implementation of any of the containers,
> or any of the "smart" pointers that does not rely on 'new'.
 
No, the containers rely on std::allocator and how this works is
exchangeable.
Unfortunately std::allocator works with new and not with some other kind
of memory-allocation. The thing is simply that when you have very large
allocations, the're not backed up by the internal heap but by contignous
pages of the OS (i.e. allocated through mmap() or VirtualAlloc(). And
when new indirectly allocates its memory with this means, you could
often grow an allocation in-place without allocation a new memory-block
at another location. If std::allocator would have a function that would
enable f.e. vector to ask if a block could be grown in-place before
moving it to another location a lot of overhead would be saved.
James Kuyper <jameskuyper@alumni.caltech.edu>: Mar 26 12:52PM -0400

On 3/26/19 12:02, Bonita Montero wrote:
 
> If you have a expensive initialization of the elemens increasing
> the size puts not much weight on that. But if you have a cheap
> initialization, growing the size might have an essential share.
 
I recommend doing careful profiling to confirm that this is a
significant problem before expending a lot of effort to avoid it. I
think you'll be surprised at just how little difference it makes - you
might even find that it's infinitesimally faster doing it the way that
seems like it should be slower.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 26 06:50PM

On 26/03/2019 16:32, Paavo Helde wrote:
> Smartpointers don't allocate anything at all, they just encapsulate
> already allocated objects.
 
Not true: std::shared_ptr may allocate a control block.
 
/Flibble
 
--
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens." –
Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
jameskuyper@alumni.caltech.edu: Mar 26 12:39PM -0700

On Tuesday, March 26, 2019 at 11:59:50 AM UTC-4, Bonita Montero wrote:
> ter is usually adjustet for each emplace_back or push_back; that's not
> very efficient compared to growing the size of the container with its
> elements not initialized in one step.
 
Either way, it's a single increment of either a counter or a pointer per
element. Such an imcrement will also occur, not necessarily in the same
variable, during the loop that executes when you initialize the array
with a large number of elements at once, so you don't actually save
anything by doing it all at once.
 
It's a very minor cost compared to all the other things that need to be
done, and not easily avoided. You should concentrate on thinking about
how many memory allocations occur, because they're fairly expensive, and
how many constructor calls occur, because they, depending upon the type,
they might be expensive.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 08:43PM +0100

> It's a very minor cost compared to all the other things that need to be
> done, ...
 
That depends on what you write.
Ian Collins <ian-news@hotmail.com>: Mar 27 08:48AM +1300

On 27/03/2019 08:43, Bonita Montero wrote:
>> It's a very minor cost compared to all the other things that need to be
>> done, ...
 
> That depends on what you write.
 
Can you cite an example and in doing so, quote correctly?
 
--
Ian.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 26 09:11PM +0100

>>> done, ...
 
>> That depends on what you write.
 
> Can you cite an example and in doing so, quote correctly?
 
No, but I can not safely rule out cases I indicated.
Ian Collins <ian-news@hotmail.com>: Mar 27 09:19AM +1300

On 27/03/2019 09:11, Bonita Montero wrote:
 
>>> That depends on what you write.
 
>> Can you cite an example and in doing so, quote correctly?
 
> No, but I can not safely rule out cases I indicated.
 
So you can't quote properly or cite an example where incrementing a
pointer is excessively expensive?
 
One is just plain rude, the other an inability to back your argument.
 
--
Ian.
"André Luis Pereira dos Santos" <pereirasantosandreluis@gmail.com>: Mar 26 10:25AM -0700

C and C++ are languages with a mature standard library, very well tested with decades of use.
This makes a difference in the security reports.
 
----------------------------------------------------------------------
André Luis Pereira dos Santos
C/C++ Development and Consultancy
www.andreconsult.tk
blog.andreconsult.tk
+55 16 98830-7133
 
Em segunda-feira, 25 de março de 2019 07:50:22 UTC-3, Juha Nieminen escreveu:
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 26 01:12AM +0100

On 25.03.2019 20:26, David Brown wrote:
 
>> /Flibble
 
> <https://en.wikipedia.org/wiki/Muphry%27s_law>
 
> (At the risk of invoking it myself, I note that you missed out the comma.)
 
<shelrock hat>Lols. As far as I can see the "guitly" party is located in
Melbourne, Australia, so it isn't you unless you used a proxy, e.g. Tor
network. However, I don't see how you could become aware of that in such
a short time frame unless you were somehow involved or with knowledge of
the edit.</shelrock hat>
 
In Norwegian:
 
Watson, stikk ut og se hva det er hunden fra Basker vil.
 
 
Cheers!,
 
- Alf
David Brown <david.brown@hesbynett.no>: Mar 26 09:17AM +0100

On 25/03/2019 21:23, Mr Flibble wrote:
>> (pthread_key_create/pthread_setspecific).
 
> "three decades" of experience!.
 
> /Flibble
 
He made a little mistake - as we all do from time to time. He realised
it, admitted it, learned from it, and moves on. That shows the maturity
of someone with three decades of experience. I'm not sure what /your/
response is showing, but "maturity" is not the word that springs to mind.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: