Subject: Re: [boost] Boost.Convert. Take 2.
From: Vladimir Batov (vb.mail.247_at_[hidden])
Date: 2014-02-21 17:04:13
alex <alexhighviz <at> hotmail.com> writes:
> >-----Original Message-----
> >From: Boost [mailto:boost-bounces <at> lists.boost.org] On Behalf Of Rob
> >Sent: 21 February 2014 15:35
> >To: boost <at> lists.boost.org
> >Subject: Re: [boost] Boost.Convert. Take 2.
> >On February 21, 2014 5:48:32 AM EST, alex <alexhighviz <at> hotmail.com>
> >>>>All loops are actually like
> >>>>for (int k = 0; k < local::num_cycles; ++k)
> >>>> int k = boost::convert<int>::from("12345", ccnv).value();
> >>>> BOOST_ASSERT(k == 12345);
> >>>>Do you think there still might be something I missed?
> >>>The assertion won't help in an optimized build, of course. Save the
> >>values and
> >>>print them at the end, after you've captured the elapsed times.
> >>Isn't it also a problem that the inside of the loop doesn't vary? A
> >>compiler may decide to evaluate boost::convert<int>::from("12345",
> >>ccnv).value() only once and re-use the result?
> >Of course, yes. I should have noticed that. Incrementing a value each
> >and printing that value at the end should work. Overflow isn't important.
> >using the final value in an opaque way will prevent optimizing away the
> >conversions in the loops.
> That seems easier said than done, because it is the value of a string that
> needs to be unpredictable?
> int sum = 0;
> for (int k = 0; k < local::num_cycles; ++k)
> char str = "12345";
> str[4 - k % 5] = 49 + k % 9; //because the char '1' has value 49
> sum += boost::convert<int>::from(str, ccnv).value();
> std::cout << sum;
Rob, Alex, thank you for the input. Humiliated by the magnitude of my own
ignorance. Learned something today. Optimized and tested as suggested.
Optimization gains seem to vary a lot depending on the compiler:
MS Visual C++ 2010 Express. Not optimized:
for user-defined type: lcast/convert=18.95/14.28 seconds.
for int type: scanf/lcast/convert=3.05/1.20/24.17 seconds.
MS Visual C++ 2010 Express. Optimized for speed:
for user-defined type: lcast/convert=6.36/2.95 seconds.
for int type: scanf/lcast/convert=0.70/0.86/5.59 seconds.
$ g++ --version
g++ (GCC) 4.8.2 Cygwin
$ g++ -O3 test_convert.cpp -I../..
for user-defined type: lcast/convert=5.42/4.14 seconds.
for int type: scanf/lcast/convert=1.08/1.16/2.38 seconds.
$ g++ -O0 test_convert.cpp -I../..
for user-defined type: lcast/convert=6.16/4.59 seconds.
for int type: scanf/lcast/convert=1.08/1.80/2.69 seconds.
Still what I am puzzled by is that lexical_cast performance table in the
docs claims to be far ahead of scanf... and I cannot reproduce their