Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>Edit 2012-04-11</h1> <p><a href="https://stackoverflow.com/users/79455/rve">rve</a> quite rightly commented about lexical_cast's performance, providing a link:</p> <p><a href="http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/performance.html" rel="nofollow noreferrer">http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/performance.html</a></p> <p>I don't have access right now to boost 1.49, but I do remember making my code faster on an older version. So I guess:</p> <ol> <li>the following answer is still valid (if only for learning purposes)</li> <li>there was probably an optimization introduced somewhere between the two versions (I'll search that)</li> <li>which means that boost is still getting better and better</li> </ol> <h1>Original answer</h1> <p>Just to add info on Barry's and Motti's excellent answers:</p> <h2>Some background</h2> <p>Please remember Boost is written by the best C++ developers on this planet, and reviewed by the same best developers. If <code>lexical_cast</code> was so wrong, someone would have hacked the library either with criticism or with code.</p> <p>I guess you missed the point of <code>lexical_cast</code>'s real value...</p> <h2>Comparing apples and oranges.</h2> <p>In Java, you are casting an integer into a Java String. You'll note I'm not talking about an array of characters, or a user defined string. You'll note, too, I'm not talking about your user-defined integer. I'm talking about strict Java Integer and strict Java String.</p> <p>In Python, you are more or less doing the same.</p> <p>As said by other posts, you are, in essence, using the Java and Python equivalents of <code>sprintf</code> (or the less standard <code>itoa</code>).</p> <p>In C++, you are using a very powerful cast. Not powerful in the sense of raw speed performance (if you want speed, perhaps <code>sprintf</code> would be better suited), but powerful in the sense of extensibility.</p> <h3>Comparing apples.</h3> <p>If you want to compare a Java <code>Integer.toString</code> method, then you should compare it with either C <code>sprintf</code> or C++ <code>ostream</code> facilities.</p> <p>The C++ stream solution would be 6 times faster (on my g++) than <code>lexical_cast</code>, and quite less extensible:</p> <pre><code>inline void toString(const int value, std::string &amp; output) { // The largest 32-bit integer is 4294967295, that is 10 chars // On the safe side, add 1 for sign, and 1 for trailing zero char buffer[12] ; sprintf(buffer, "%i", value) ; output = buffer ; } </code></pre> <p>The C <code>sprintf</code> solution would be 8 times faster (on my g++) than <code>lexical_cast</code> but a lot less safe:</p> <pre><code>inline void toString(const int value, char * output) { sprintf(output, "%i", value) ; } </code></pre> <p>Both solutions are either as fast or faster than your Java solution (according to your data).</p> <h3>Comparing oranges.</h3> <p>If you want to compare a C++ <code>lexical_cast</code>, then you should compare it with this Java pseudo code:</p> <pre><code>Source s ; Target t = Target.fromString(Source(s).toString()) ; </code></pre> <p>Source and Target being of whatever type you want, including built-in types like <code>boolean</code> or <code>int</code>, which is possible in C++ because of templates.</p> <h2>Extensibility? Is that a dirty word?</h2> <p>No, but it has a well known cost: When written by the same coder, general solutions to specific problems are usually slower than specific solutions written for their specific problems.</p> <p>In the current case, in a naive viewpoint, <code>lexical_cast</code> will use the stream facilities to convert from a type <code>A</code> into a string stream, and then from this string stream into a type <code>B</code>.</p> <p>This means that as long as your object can be output into a stream, and input from a stream, you'll be able to use <code>lexical_cast</code> on it, without touching any single line of code.</p> <h2>So, what are the uses of <code>lexical_cast</code>?</h2> <p>The main uses of lexical casting are:</p> <ol> <li>Ease of use (hey, a C++ cast that works for everything being a value!)</li> <li>Combining it with template heavy code, where your types are parametrized, and as such you don't want to deal with specifics, and you don't want to know the types.</li> <li>Still potentially relatively efficient, if you have basic template knowledge, as I will demonstrate below</li> </ol> <p>The point 2 is very very important here, because it means we have one and only one interface/function to cast a value of a type into an equal or similar value of another type.</p> <p>This is the real point you missed, and this is the point that costs in performance terms.</p> <h2>But it's so slooooooowwww!</h2> <p>If you want raw speed performance, remember you're dealing with C++, and that you have a lot of facilities to handle conversion efficiently, and still, keep the <code>lexical_cast</code> ease-of-use feature.</p> <p>It took me some minutes to look at the lexical_cast source, and come with a viable solution. Add to your C++ code the following code:</p> <pre><code>#ifdef SPECIALIZE_BOOST_LEXICAL_CAST_FOR_STRING_AND_INT namespace boost { template&lt;&gt; std::string lexical_cast&lt;std::string, int&gt;(const int &amp;arg) { // The largest 32-bit integer is 4294967295, that is 10 chars // On the safe side, add 1 for sign, and 1 for trailing zero char buffer[12] ; sprintf(buffer, "%i", arg) ; return buffer ; } } #endif </code></pre> <p>By enabling this specialization of lexical_cast for strings and ints (by defining the macro <code>SPECIALIZE_BOOST_LEXICAL_CAST_FOR_STRING_AND_INT</code>), my code went 5 time faster on my g++ compiler, which means, according to your data, its performance should be similar to Java's.</p> <p>And it took me 10 minutes of looking at boost code, and write a remotely efficient and correct 32-bit version. And with some work, it could probably go faster and safer (if we had direct write access to the <code>std::string</code> internal buffer, we could avoid a temporary external buffer, for example).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload