2

Let's say there's a section of code which takes a big chunk of the overall program time (~20%), which consists on converting from a given type (among options: string, char, short, int, float, unsigneds, ...) to string. The easy way to do this would be something like:

template<class T>
string toString(T sAttrvalue) {
    stringstream ss;
    ss << T;

    string res=ss.str();

    if(res=="x" || res=="y")
        return "k";

    return res;
}

But the performance is too poor (even if it improves by using a static stringstream and doing ss.str("") in the beginning of the function).

Any other ideas on how to make it go faster? (what would you think of using another function argument which specifies the time and, from there, use sprintf?)

gcandal
  • 937
  • 8
  • 23
  • Do you know which type (char, short, int, float) that you are most often converting? `stringstream` isn't exactly famous for its speed, so it may be worth (assuming it's really worth the effort) to convert "by hand". Integer conversion is pretty simple - floating point is a bit worse... And of course, having an `if (res == "x" ....` for integers is pretty meaningless.. – Mats Petersson Jul 24 '13 at 15:04
  • Every type is used an almost equal amount of time. – gcandal Jul 24 '13 at 15:05
  • Have you tried measuring which takes the most time? – Mats Petersson Jul 24 '13 at 15:06
  • If you can use c++11, std::to_string() would be more suitable because you don't need stream features. – Vincent Jul 24 '13 at 15:10
  • What you have is basically similar to Boost lexical_cast -- but recent iterations of it include specializations for many common types, so using it might be helpful. – Jerry Coffin Jul 24 '13 at 15:12
  • I have not, how could I measure accurately? Cannot use boost or C++11, it must run on an old system and maintain portability. – gcandal Jul 24 '13 at 15:25
  • Refer to http://stackoverflow.com/a/1251043/560648. – Lightness Races in Orbit Jul 24 '13 at 16:28

2 Answers2

3

You could try using template specialization in addition to the code you gave, to optimize the most common cases (this is how, for example, vector<bool> can be more space-efficient).

For example:

template<>
string toString<char>(char sAttrValue) {
    ...
}

template<>
string toString<int>(int sAttrValue) {
    ...
}

And so on for the other types, each one using a conversion method specific and optimized for that type. Any type that doesn't match one of these specialized templates will fall back to the default stringstream method.

Drew McGowen
  • 11,471
  • 1
  • 31
  • 57
3

A few points:

  • to measure accurately, get time snapshot, call the function in a loop for X times (say X = 10000), then get time again (see clock()). Substract initial time from final time and divide by X.

    This will give you an accurate measurement.

  • ostringstream is not made for performance, it is made for uniform, extensible buffered output (buffered = slow).

    You should particularize the template by type and use faster alternatives. If possible, do not switch to sprintf, but use other alternatives (itoa, allocate string directly, etc).

    If you do use sprintf, be paranoid about it (check return value, corner cases, etc).

utnapistim
  • 26,809
  • 3
  • 46
  • 82
  • That is _not_ how to measure accurately. If the library isn't broken, using `clock()` before and after should work; on Windows (where `clock()` is broken), you'll have to use `GetProcessTimes`. – James Kanze Jul 24 '13 at 15:43
  • + I use your method. High accuracy of time measurement is not important, unless a race is being run and it's important to resolve who the winner is. – Mike Dunlavey Jul 24 '13 at 16:05
  • @JamesKanze, I know - I meant "measure time" (not "local time"). I will correct. – utnapistim Jul 24 '13 at 16:41