|
Boost : |
Subject: Re: [boost] sentinels vs iterators (was: NTCTS Iterator)
From: Joaquin M Lopez Munoz (joaquin_at_[hidden])
Date: 2014-08-21 06:12:49
Eric Niebler <eniebler <at> boost.org> writes:
>
> On 08/20/2014 07:40 AM, Beman Dawes wrote:
> >
> > See http://beman.github.io/ntcts_iterator/
> >
> > or https://github.com/Beman/ntcts_iterator
>
> The need for such a thing is an unfortunate side-effect of the fact that
> a range's begin and end iterators must have the same type. I'm building
> a range library that loosens that restriction and writing a proposal to
> get it into the standard.
Hi Eric,
This might be connected in a way with your sentinel idea. Some
months ago I explored a container-like construct for polymorphic
objects that group elements by run-time type so as to greatly
speed up for_each processing:
http://bannalia.blogspot.com.es/2014/05/fast-polymorphic-collections.html
This poly_collection class (currently just a sketch to show the
underlying ideas) has a for_each member function
template<typename F> F for_each(F f);
that internally dispatches to the different same-type chunks
the collection is comprised of:
template<typename F>
F for_each(F f)
{
for(const auto& p:chunks)p.second->for_each(f);
return std::move(f);
}
The performance gains are massive, as shown in the article. Now, if
we wished to use the standard for_each algorithm rather than
the provided member function:
poly_collection<base> c;
...
std::foreach(c.begin(),c.end(),f);
then poly_collection would have to implement an iterator type
that sequentally traverses all the chunks, which implies a fairly
expensive increment operation (in pseudocode):
iterator& operator++()
{
node+=chunk_element_size;
if(node==chunk_end()){
node=next_chunk_begin(node);
}
return *this;
}
That is, incrementing involves checking against chunk end, which,
combined with the begin!=end check of std::for_each, implies two
checks per step. This is slower than poly_collection::for_each,
which can get by with just one check per step.
I wonder: maybe a sentinel-based range can be used so that
std::for_each(c,f) is as efficient as c.for_each(f) for a
poly_collection c?
JoaquÃn M López Muñoz
Telefónica
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk