1
\$\begingroup\$

I drafted a method that I intend to use to convert integers to strings. Is there a way to make it faster? Are there any "simple" changes I could make to improve its performance? This cannot be done with C++11.

std::string to_string(int val) {
    static std::string str;
    static std::stringstream ss;
    ss << val;
    ss >> str;
    ss.clear();
    return str;
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Have you considered what would happen if you change the parameter from int to any other type? It still works (as long as there is the appropriate operator<< define. So if you make this a template function it should work with all types. Boost did something like this with boost::lexical_cast<>() \$\endgroup\$ Commented Oct 13, 2014 at 17:51

1 Answer 1

2
\$\begingroup\$

I have a big concern with this code. It uses local static variables, so this will result in race conditions if used in a multithreaded program.

I assume you did that to improve performance? Constructing the std::stringstream could potentially incur some overhead. So having that variable as a static would be understandable if you are sure no race conditions apply. But the str string certainly doesn't have to be a local static. Actually, it is not needed at all, since stringstream::str() exists.

I think you have two options here:

Make it thread-safe and cleaner at the cost of some extra object construction every call, which is probably not a big deal:

std::string to_string(int val) {
    std::stringstream ss;
    ss << val;
    return ss.str();
}

Or, if you need ultimate performance and cannot afford the chance of a memory allocation by std::stringstream, then you could use sprintf, snprintf or itoa. This is a possible implementation, also thread safe, with no statics:

std::string to_string(int val) {
    // Buffer size is arbitrary in this example. Could be smaller.
    // 128 is more than enough for any integer number.
    char buffer[128];
    std::snprintf(buffer, sizeof(buffer), "%i", val);
    return buffer;
}

I suggest going with the first one, but if you have a justifiable performance concern, then the second one should perform slightly better.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks, I think I will stick with the second one. I have no idea how many times that method will be called every second right now. I forgot about stringstream::str(). \$\endgroup\$ Commented Oct 13, 2014 at 15:09
  • \$\begingroup\$ There is no itoa in C++. There is std::to_string, though. \$\endgroup\$
    – Cubbi
    Commented Oct 16, 2014 at 3:52
  • \$\begingroup\$ @Cubbi, yes, itoa is not standard. It is noted in the link I've added. Didn't mention std::to_string because the question is not tagged as C++11, so... \$\endgroup\$
    – glampert
    Commented Oct 16, 2014 at 4:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.