Boost logo

Boost :

Subject: Re: [boost] [lexical_cast] Fast conversion from boost::iterator_range<std::string::iterator>?
From: Matthew Chambers (matt.chambers42_at_[hidden])
Date: 2011-11-23 17:13:49


On 11/23/2011 11:55 AM, Olaf van der Spek wrote:
> On Wed, Nov 23, 2011 at 5:55 PM, Matthew Chambers wrote:
>> On Oct 13, 2011 Michel Morin wrote:
>>>
>>> lexical_cast made optimizations for some types (such as `std::string`)
>>> to achieve better performance. But, from my experience,
>>> it seems that lexical_cast does not make any optimization for
>>> `boost::iterator_range<std::string::iterator>`.
>>>
>>> Is there any plan to add optimization for such iterator ranges?
>>> Currently,
>>> - `lexical_cast<int>(std::string(iter_rng.begin(), iter_rng.end()))`
>>> is faster
>>> than `lexical_cast<int>(iter_rng)`.
>
> Why's that?

Why is it faster? Presumably because lexical_cast has optimized specializations for std::string but
not for iterator_range<std::string::iterator>. So creating a new string from the range invokes the
optimized specialization and ends up being faster.

>>> - Assuming it is safe to use `std::atoi`,
>>> `std::atoi(&iter_rng.front())` is faster
>>> than both of the above two methods.
>
> Is front() guaranteed to return a 0-terminated string?

Certainly not. I consider that caveat to be part of the "assuming it is safe" precondition. He's
just saying that there is potential to be faster. Although he didn't compare lexical_cast<int> on a
string without copying the string, which should be comparable to atoi.

I put together a test (http://codepad.org/lKxMXOwP):

1000000 iterations of "123":
atoi: 0.0695092 seconds
strtol: 0.0652839 seconds
Spirit: 0.546789 seconds
lexical_cast(string): 0.615594 seconds
lexical_cast(iterator_range): 4.25534 seconds
lexical_cast(iterator_range->string): 1.07405 seconds

1000000 iterations of "123567890":
atoi: 0.0856611 seconds
strtol: 0.0829571 seconds
Spirit: 0.905017 seconds
lexical_cast(string): 0.762137 seconds
lexical_cast(iterator_range): 7.46185 seconds
lexical_cast(iterator_range->string): 1.23397 seconds

1000000 iterations of "1.23456":
atof: 0.520452 seconds
strtod: 0.519113 seconds
Spirit: 1.02579 seconds
lexical_cast(string): 2.93515 seconds
lexical_cast(iterator_range): 6.62648 seconds
lexical_cast(iterator_range->string): 3.73831 seconds

1000000 iterations of "1.23456789e42":
atof: 0.711819 seconds
strtod: 0.719144 seconds
Spirit: 1.48992 seconds
lexical_cast(string): 3.31997 seconds
lexical_cast(iterator_range): 9.87004 seconds
lexical_cast(iterator_range->string): 4.20932 seconds

-Matt


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