2

There are sooo many posts about converting from int to string but they all really involve either just printing to the screen, or using ostringstream.

I was using ostringstream, but my company doesnt want me to use any streams because it has horrid runtimes.

I was doing this in a C++ file.

my issue is that i was going to, over the course of execution create millions of streams, write to the buffers, and then copy content into a string, as such:

ostringstream OS;
os << "TROLOLOLOLOL";
std::string myStr = os.str();

There is redundancy as it is making this buffer then copying it all over. UGH!

Fallenreaper
  • 10,222
  • 12
  • 66
  • 129
  • 1
    Your example doesn't make sense, why not just do `std::string myStr( "TROLOLOLOLOL" );`? Or do you want to build a string incrementally? – Praetorian Nov 13 '12 at 17:30
  • Some hints are here: http://stackoverflow.com/questions/3799595/itoa-function-problem – PiotrNycz Nov 13 '12 at 17:31
  • 1
    The "horrid runtimes" argument is bullshit. I've tested and found maybe a 10% difference on some occasions, if you bother to set a buffer and don't do anything too boneheaded. – cHao Nov 13 '12 at 17:32
  • Yea, i dunno why they say that, but i personally have not tested it, as it is not what im paid to do.. My example was pretty much doing that above code like 2.3million times – Fallenreaper Nov 13 '12 at 17:34
  • 1
    @cHao That isn't a completely bullshit statement. [Here's a great example of it.](http://stackoverflow.com/questions/4340396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali) But it may or may not apply to this particular example the OP is hitting. – Mysticial Nov 13 '12 at 17:34
  • @Mysticial: It's not *completely* bullshit, but the difference isn't anywhere near as big as some idiot's benchmarks would have you believe. Like i said, about 10% on some occasions. Others, i've seen iostreams actually be *faster* when someone bothered to try for performance. – cHao Nov 13 '12 at 18:20
  • @cHao That is good to know. Maybe i am just doing it wrong. I was thinking that creating streams/buffers, writing to them and copying it all out was just very time confusing. Was hoping there was a way to do it better. *shrug* – Fallenreaper Nov 13 '12 at 18:27

4 Answers4

6

In C++11:

string s = std::to_string(42);

I did a benchmark a couple of weeks ago, and got those results (using clang and libc++ shipped with current Xcode):

stringstream took 446ms
to_string took 203ms
c style took 170ms

With the following code:

#include <iostream>
#include <chrono>
#include <sstream>
#include <stdlib.h>

using namespace std;

struct Measure {
  chrono::time_point<chrono::system_clock> _start;
  string _name;

  Measure(const string& name) : _name(name) {
    _start = chrono::system_clock::now();
  }

  ~Measure() {
    cout << _name << " took " << chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - _start).count() << "ms" << endl;
  }
};



int main(int argc, const char * argv[]) {
  int n = 1000000;
  {
    Measure m("stringstream");
    for (int i = 0; i < n; ++i) {
      stringstream ss;
      ss << i;
      string s = ss.str();
    }
  }
  {
    Measure m("to_string");
    for (int i = 0; i < n; ++i) {
      string s = to_string(i);
    }
  }
  {
    Measure m("c style");
    for (int i = 0; i < n; ++i) {
      char buff[50];
      snprintf(buff, 49, "%d", i);
      string s(buff);
    }
  }
  return 0;
}
lucas clemente
  • 6,255
  • 8
  • 41
  • 61
  • That is a solid bench mark, and over the datasets i need to, makes a HUGE difference. I might end up doing the c style approach – Fallenreaper Nov 13 '12 at 17:39
  • You could try reusing the buffer, dunno if that helps a lot. – lucas clemente Nov 13 '12 at 17:40
  • 2
    Using this same benchmark, but moving the stream creation outside the loop and saying `ss.str("");` to clear it each iteration, i get 190ms runtimes as opposed to `to_string`'s 191ms. `snprintf` is just slightly faster at 169ms. – cHao Nov 13 '12 at 18:05
  • @cHao the implementation matters a lot as well. For example, even with stream creation moved outside the loop on Windows stringstream is still much slower than to_string and sprintf. – bames53 Nov 13 '12 at 18:31
3

In C++11 you have std::to_string. Although it probably uses the stringstream technique under the hoods.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

You should take a look at the performance chart of boost::lexical_cast:

http://www.boost.org/doc/libs/1_52_0/doc/html/boost_lexical_cast/performance.html

It compares lexical_cast to stringstream (with and without construction) and scanf/printf.

In most cases boost::lexical_cast is faster than scanf, printf, std::stringstream.

Anonymous Coward
  • 6,186
  • 1
  • 23
  • 29
0

Reusing the stringstream buffer. Note, this is not thread safe.

#include <sstream>
#include <iostream>
#include <string>

template<class T>
bool str_to_type(const char *str, T &value) {
  static std::stringstream strm;
  if ( str ) {
    strm << std::ends;
    strm.clear();
    strm.setf(std::ios::boolalpha);
    strm.seekp(0);
    strm.seekg(0);
    strm << str << std::ends;
    strm >> value;
    return !strm.fail();
  }
  return false;
}

int main(int argc, char *argv[])
{
  int i;
  if (!str_to_type("42", i))
    std::cout << "Error" << std::endl;
  std::cout << i << std::endl;
    return 0;
}
Unkle George
  • 126
  • 1
  • 3