Boost logo

Boost :

Subject: Re: [boost] lifetime of ranges vs. iterators
From: David Abrahams (dave_at_[hidden])
Date: 2008-09-03 09:05:48


on Tue Sep 02 2008, Arno Schödl <aschoedl-AT-think-cell.com> wrote:

>> I'm trying to find out what the specific example applications are. I
>> have a suspicion that range adapters or single-level iterator adaptors
>> may not be the best way to address these applications and may even
>> sacrifice significant performance, but I can't tell until I know what
>> the applications are. Just so, single-level iterators (or ordinary
>> range adapters, which don't add anything conceptually to iterators) are
>> not the best way to address iteration over hierarchical data structures,
>> which is why we have segmented iterators.
>
> This is a typical one, copied straight from our code:
>
> grdlns->InsertGridlines(
> vecgvepsSource,
> make_first_range(vecpairanchorsrcgrdln),
> GridlineInsertionPositions(
> make_transform_range(
> make_transform_range(
> make_first_range(
> vecpairanchorsrcgrdln ),
> boost::mem_fn(&_vector<
> Ref<CGridlineAnchor> >::begin)
> ),
> boost::mem_fn( &CGridlineAnchor::Binding
> )
> ),
> vecgrdlnSnapped),
> vecgrdlnSnapped
> );

The first problem is that I can't tell what that does. So it doesn't
really begin to answer the question.

> This is a case in point: I did not write this code, and in the absence of
> specific guidelines against, the programmer decided to stack transform_range. In
> this case, performance-wise, this is no better or worse than using a single
> transform_range with boost::bind. Likewise, people may innocently write
>
> rng | filtered( funcA )
> | filtered( funcB )
> | filtered( funcC )
> | filtered( funcD )
> | filtered( funcE )
>
> blissfully unaware of any performance penalty.

Yes, but:

 1. _Do_ they write that?

 2. If they do that, I believe they are still paying an enormous
    unnecessary runtime penalty even with your optimization because of
    the endpoint checks in each layer of the composite iterator or
    range. The only way IIUC to avoid such a penalty is to compress the
    filter adapters into one, essentially by using expression
    templates.

 3. I am not yet convinced that you are suffering a significant
    performance penalty due to the wasted space in real applications.
    Have you measured it? Unless you're actually *storing* lots of
    these stacked iterators or passing them around by value in your
    inner loops, it seems unlikely to make much of a difference.

 4. I can understand wanting to improve these components so that they
    can be efficient under more conditions, and avoiding the redundant
    storage would undoubtedly be a real improvement. However, I think
    there's a deeper inefficiency in stacking all those filter iterators
    together, and it's neither a range library's job, nor I think is it
    possible in this case, to protect users from "blissful unawareness"
    of performance implications.

>> However, it seems to me that you already have a general answer in mind,
>> and it might be better to back up and look at the real problems you want
>> to solve before moving on to the answer.
>
> Would it be my turn now to ask for some credit ;-) ?

Take as much as you like, but -- sorry -- I'm not yet convinced we're
solving a real problem here, and if it _is_ real, I am not quite
convinced the general approach of squeezing out redundant storage would
address all of the problem.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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