How can I improve formatting number with commas performance?

霸气de小男生 提交于 2019-12-07 07:58:43

问题


I'm using the following method to format a number with commas:

template<class T>
static std::string FormatNumberWithCommas(T value, int numberOfDecimalPlaces = 0)
{
    std::stringstream ss;
    ss.imbue(std::locale(""));
    ss.precision(numberOfDecimalPlaces);
    ss << std::fixed << value;
    return ss.str();
}

Profiling has show this method to take a significant amount of time relative to other code. Specifically the profiler has identified the line:

ss.imbue(std::locale(""));

And within that I believe it is the std::locale("") that is taking long. How can I improve the performance of this method? If it requires using something other than stringstream or doing something semi-hacky in this particular method I'm open to it.


回答1:


You could start by making the string stream a static variable:

{
  static std::stringstream ss;
  static bool ss_init = false;
  static std::string emtpy_string;
  if (!ss_init) { ss.imbue(std::locale("")); ss_init = true; }

  ss.str(empty_string);
  // ...
}

If that's still a bottleneck, you could look at an alternative formatting library like fastformat.




回答2:


1 using namespace std;

2 template <typename T>
3 string AddCommas(T data);

4 template <>
5 string AddCommas<int>(int data)
6 { 
7   stringstream ss; ss << data; string s = ss.str();
8   if (s.length() > 3)
9       for (int i = s.length()-3; i > 0; i -= 3)
10          s.insert(i,",");
11  return s;
12 }

You can use the same code for long. Double is a little trickier.

13 template <>
14 string AddCommas<double>(double data)
15 {
16  stringstream ss; ss << fixed << data; string s = ss.str();
17  string intPart, decPart = "";
18  int pos = s.find('.');
19  if (pos != string::npos) {
20      intPart = s.substr(0,pos);
21      decPart = s.substr(pos,pos-s.length());
22      //remove trailing zeros
23      for (int i = decPart.length()-1; i > 0; i--) {
24          if (decPart[i] == '0') decPart.erase(i);
25          else break;
26      }
27      // remove decimal point if no decimals
28      if (decPart.length() == 1) decPart = "";
29  }
30  else intPart = s;
31  //insert commas
32  if (intPart.length() > 3) {
33      for (int i = intPart.length()-3; i > 0; i -= 3) intPart.insert(i,",");
34  }
35  s = intPart + decPart;
36  return s;
37 }

You can make one for float. The only problem arises if you want to set precision. Then you have to just make a stand alone function and add a parameter for precision. Also you would need to change some of the code:

ss << fixed << setprecision(precision) << data; //...

As well as remove lines 22 through 28.



来源:https://stackoverflow.com/questions/7693751/how-can-i-improve-formatting-number-with-commas-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!