如何使用逗号性能改进格式编号?

时间:2011-10-07 23:25:28

标签: c++ performance optimization stringstream

我正在使用以下方法用逗号格式化数字:

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();
}

分析显示此方法相对于其他代码需要花费大量时间。具体而言,探查者已经确定了这一行:

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

在此之内,我相信这是std::locale("")需要很长时间。如何提高此方法的性能?如果它需要使用stringstream之外的其他东西或者在这种特殊的方法中做一些半hacky,我会对它开放。

2 个答案:

答案 0 :(得分:4)

您可以首先将字符串流设为静态变量:

{
  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);
  // ...
}

如果这仍然是一个瓶颈,你可以看一下像fastformat这样的替代格式库。

答案 1 :(得分: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 }

您可以长时间使用相同的代码。 Double有点棘手。

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 }

你可以为浮动制作一个。如果要设置精度,唯一的问题就出现了。然后你必须只做一个独立的功能并添加一个精度参数。您还需要更改一些代码:

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

除了删除22到28行。