Boost logo

Boost :

Subject: Re: [boost] [Range] Range adaptor approach for temporary range lifetime issue
From: Michel Morin (mimomorin_at_[hidden])
Date: 2012-06-28 11:34:41


Jeffrey Lee Hellrung, Jr. wrote:
>> Repeatedly adapted ranges might have **very** large size.
>> For example, on Mac OS X 10.7 with gcc-4.7,
>>
>>    std::vector<int> v;
>>
>>    sizeof(v | uniqued)                               --> 32
>>    sizeof(v | uniqued | uniqued)                     --> 80
>>    sizeof(v | uniqued | uniqued | uniqued)           --> 176
>>    sizeof(v | uniqued | uniqued | uniqued | uniqued) --> 368
>>
>>    // OvenToBoost's taken adaptor
>>    sizeof(v | taken(1))                                  --> 48
>>    sizeof(v | taken(1) | taken(1))                       --> 112
>>    sizeof(v | taken(1) | taken(1) | taken(1))            --> 240
>>    sizeof(v | taken(1) | taken(1) | taken(1) | taken(1)) --> 496
>>
>>    sizeof(v | strided(1))                                        --> 80
>>    sizeof(v | strided(1) | strided(1))                           --> 272
>>    sizeof(v | strided(1) | strided(1) | strided(1))              --> 848
>>    sizeof(v | strided(1) | strided(1) | strided(1) | strided(1)) --> 2576
>>
>
> Wow. I might investigate what this looks like with this alternative range
> adaptor implementation I've been suggesting (i.e., a lazy implementation
> rather than the iterator-based implementation presently in Boost.Range).

Range forwarders (e.g. uniqued, taken(1), strided(1), etc.) are generally
lightweight, and so the lazy implementation should also be lightweight.

As for moved_range, avoiding caching adapted ranges greatly reduces
its size. Indeed, whether or not caching adapted ranges was one of my
major concerns in implementing moved_range.
moved_range stores a moved container and a fusion vector of
range forwarders. Without caching an adapted range,
the container have to be adapted each time begin or end is called.
This means that a single pair of begin/end calls requires adapting
two pairs of begin/end iterators. This seems inefficient, and so I chose to
cache an adapted range in moved_range.

However, I cannot predict how badly this size problem affects
the performance, because my knowledge about copy elision is scarce...

Regards,
Michel


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