
Hi, I'm preparing a patch to improve a performance of lexical_cast for certain combinations of types. For example, int to char transformation is 5.9 times faster on my FreeBSD. It could be even faster if not a requirement to add a thousands separator. There are few issues I'd like to sort out before I finish the work. 1. Enums, unlike integral types, are not optimized. I don't want to break a conversion from enums with user-defined operator<<. My firm opinion on this is not to support this edge case and allow optimization. 2. To improve a performance even further, I'd like to add lexical_cast< boost::array<N,char> >(arg) but it would break InputStreamable requirement. 3. A couple of conversion functions are good candidates for .cpp file. I expect a strong resistance to this change. Don't get me wrong, I'm not going to change this in default build, I'm asking for new configuration parameter. Something like BOOST_LINK_CORELIB. A user should always link with -lboost_core if BOOST_LINK_CORELIB is defined. That do you think? -- Alexander Nasonov Project Manager at Akmosoft ( http://www.akmosoft.com ) Blog: http://nasonov.blogspot.com Email: $(FirstName) dot $(LastName) at gmail dot com

On Thu, 6 Jul 2006 22:56:52 +0400, Alexander Nasonov <alnsn@yandex.ru> wrote:
Hi, I'm preparing a patch to improve a performance of lexical_cast for certain combinations of types. [...] That do you think?
My memory on this is quite blurred, but long time ago Terje Slettebo did a complete rewrite of lexical_cast<>, in this direction (I haven't looked at your code though). In the end, however, the current solution was preferred, I guess for its simplicity. That doesn't mean you cannot have another take at it, but I'd suggest to search for old posts and ask what the current consensus is before investing time on it. -- [ Gennaro Prota, C++ developer for hire ] [ resume: available on request ]

My memory on this is quite blurred, but long time ago Terje Slettebo did a complete rewrite of lexical_cast<>, in this direction (I haven't looked at your code though). I forwarded your message to Terje. My solution is not a complete rewrite. Some source types are routed to lexical_stream_limited. It doesn't have stringstream member but rather a pointer to local buffer (those source types are always
Gennaro Prota wrote: limited in length). I use custom algorithms to place a source value to the buffer because it's faster. Though, I could use streambuf and ostream to format to the buffer without additional allocations. I use streambuf and istream for input phase except wstring and string types (it's not different from old lexical_stream) and CharT. All other target types are read using istream and streambuf that points to the buffer.
In the end, however, the current solution was preferred, I guess for its simplicity. That doesn't mean you cannot have another take at it, but I'd suggest to search for old posts and ask what the current consensus is before investing time on it. I'm waiting for a reply from Terje.
-- Alexander Nasonov Project Manager at Akmosoft ( http://www.akmosoft.com ) Blog: http://nasonov.blogspot.com Email: $(FirstName) dot $(LastName) at gmail dot com

On Thu, 06 Jul 2006 21:18:14 +0200, Gennaro Prota <gennaro_prota@yahoo.com> wrote:
My memory on this is quite blurred, but long time ago Terje Slettebo did a complete rewrite of lexical_cast<>, in this direction (I haven't looked at your code though). In the end, however, the current solution was preferred, I guess for its simplicity.
I have to say that, now that a standardization proposal exists for it, which explicitly hints at optimized specializations, your idea is definitely worth applying regardless of what was done illo tempore. -- [ Gennaro Prota, C++ developer for hire ] [ resume: available on request ]

Gennaro Prota wrote:
I have to say that, now that a standardization proposal exists for it, which explicitly hints at optimized specializations, your idea is definitely worth applying regardless of what was done illo tempore.
There is still no reply from Terje but I'm going to apply my patch anyway as soon as it's ready and works on broken compilers (e.g. Borland). I googled for lexical_cast on www.open-std.org recently but found no proposal. Now I see it: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1973.html Thanks!

Alexander Nasonov wrote:
I googled for lexical_cast on www.open-std.org recently but found no proposal. Now I see it: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1973.html
BTW, 1. unsetf(std::ios::skipws) is not mentioned in the doc 2. loopback tests may fail N1973: "If std::numeric_limits<Target>::is_specialized, the underlying stream precision is set according to std::numeric_limits<Target>::digits10 + 1, otherwise if std::numeric_limits<Source>::is_specialized, the underlying stream precision is set according to std::numeric_limits<Source>::digits10 + 1." See http://article.gmane.org/gmane.comp.lib.boost.devel/145097

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Alexander Nasonov | Sent: 12 July 2006 16:27 | To: boost@lists.boost.org | Subject: Re: [boost] [lexical_cast] performace patch | | Alexander Nasonov wrote: | >I googled for lexical_cast on www.open-std.org recently but | found no proposal. Now I see it: | >http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1973.html | | BTW, | | 1. unsetf(std::ios::skipws) is not mentioned in the doc | 2. loopback tests may fail | | N1973: "If std::numeric_limits<Target>::is_specialized, the | underlying stream precision is set according to | std::numeric_limits<Target>::digits10 + 1, otherwise if | std::numeric_limits<Source>::is_specialized, the underlying | stream precision is set according to | std::numeric_limits<Source>::digits10 + 1." | | See http://article.gmane.org/gmane.comp.lib.boost.devel/145097 As I said before - it is the wrong formula :-(( It gives the wrong number of digits for float and will probably also fail for user defined types. Since it is for TR2, it should be specified in terms of max_digits10, now accepted for TR2. I suggest you use the right formula from digits not digits10 for now. If you've serialized a lot of stuff, you might be cross not to get back as near as possible what you've saved. And you'd probably waste a lot of time trying to find out why not. (This is a separate issue from the double loopback failures - even in MSVC, float loopback IS correct for ALL float values - there are few enough of them for an exhaustive test ;-) Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

I'm sure this will help some people. It would be nice at the same time if you could ensure that lexical_cast doesn't produce a blizzard of warnings if compiled in "strict" mode (MS level 4). Some people would like to use this option to check their own code, but are deterred by the noise from lexical_cast. This just needs some pushing and popping of warning levels (or the re-writing of some ifs before returns - the current code is correct but the compiler can't see that and so issues a warning). I also note that the expression for calculating the precision is STILL wrong and will fail loopback tests, and especially annoying to serious with serialisation. I thought this had been corrected at 1.34. It should be max_digits10. stream.precision(2 + std::numeric_limits<Source>::digits * 301/1000); http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf If you are concerned with speed this could be replaced by a constant macro when specialising double, float and long double for example. #define FLT_MAXDIG10 (2+(FLT_MANT_DIG * 3010)/10000) #define DBL_MAXDIG10 (2+ (DBL_MANT_DIG * 3010)/10000) #define LDBL_MAXDIG10 (2+ (LDBL_MANT_DIG * 3010)/10000) which yield the following values on typical implementations: FLT_DIG 6, FLT_MAXDIG10 9 DBL_DIG 15, DBL_MAXDIG10 17 LDBL_DIG 19, LDBL_MAXDIG10 21 http://www2.open-std.org/JTC1/SC22/WG14/www/docs/n1151.pdf Thanks Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com | -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Alexander Nasonov | Sent: 06 July 2006 19:57 | To: Boost developers list | Subject: [boost] [lexical_cast] performace patch | | Hi, | I'm preparing a patch to improve a performance of lexical_cast | for certain combinations of types. | For example, int to char transformation is 5.9 times faster on | my FreeBSD. It could be even faster if not a requirement to add | a thousands separator. | | There are few issues I'd like to sort out before I finish the work. | | 1. Enums, unlike integral types, are not optimized. I don't want | to break a conversion from enums with user-defined operator<<. | My firm opinion on this is not to support this edge case and | allow optimization. | | 2. To improve a performance even further, I'd like to add | lexical_cast< boost::array<N,char> >(arg) but it would break | InputStreamable requirement. | | 3. A couple of conversion functions are good candidates for | .cpp file. | I expect a strong resistance to this change. Don't get me wrong, | I'm not going to change this in default build, I'm asking for new | configuration parameter. Something like BOOST_LINK_CORELIB. | A user should always link with -lboost_core if BOOST_LINK_CORELIB | is defined. | | That do you think? | | -- | Alexander Nasonov | Project Manager at Akmosoft ( http://www.akmosoft.com ) | Blog: http://nasonov.blogspot.com | Email: $(FirstName) dot $(LastName) at gmail dot com |

It would be nice at the same time if you could ensure that lexical_cast doesn't produce a blizzard of warnings if compiled in "strict" mode (MS level 4). OK, I'll check it.
I also note that the expression for calculating the precision is STILL wrong and will fail loopback tests, and especially annoying to serious with serialisation. I thought this had been corrected at 1.34. I remember this problem. It is next in my list of lexical_cast improvements. Not sure that loopback test is solvable, though. Thanks for the links, they will help to refresh my memory.

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Alexander Nasonov | Sent: 07 July 2006 10:19 | To: boost@lists.boost.org | Subject: Re: [boost] [lexical_cast] performace patch | | >It would be nice at the same time if you could ensure that | > lexical_cast doesn't produce a blizzard of warnings if | > compiled in "strict" mode (MS level 4). | OK, I'll check it. | | >I also note that the expression for calculating the precision is | > STILL wrong and will fail loopback tests, and especially annoying | > to serious with serialisation. I thought this had been corrected | > at 1.34. | I remember this problem. It is next in my list of lexical_cast improvements. :-) | Not sure that loopback test is solvable, though. Problem is iostream library writers' problem reading digits into streams, not lexical_cast - and only a problem with those which are a tiny bit broken (EG MSVC). Thanks Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com
participants (3)
-
Alexander Nasonov
-
Gennaro Prota
-
Paul A Bristow