我正在使用以下方法用逗号格式化数字:
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,我会对它开放。
答案 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行。