string A = "test";
double B = 123.45;
float C = 43.23;
char D = 'c';
试图加入他们以产生一个字符串string res = "test,123.45,43.23,c"
。最快的方法是什么?
ostringstream
很好,但似乎不够快。
string A = "test";
double B = 123.45;
float C = 43.23;
char D = 'c';
试图加入他们以产生一个字符串string res = "test,123.45,43.23,c"
。最快的方法是什么?
ostringstream
很好,但似乎不够快。
我不知道最快的方法。我只知道如何在 C++ 中完成它。:)
这是一个演示程序,显示了两种方法
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string A = "test";
double B = 123.45;
float C = 43.23;
char D = 'c';
std::string res1 = A + ',' + std::to_string( B ) + ',' +
std::to_string( C ) + ',' + D;
std::cout << res1 << std::endl;
std::ostringstream is;
is << A << ',' << B << ',' << C << ',' << D;
std::string res2 = is.str();
std::cout << res2 << std::endl;
return 0;
}
程序输出为
test,123.450000,43.230000,c
test,123.45,43.23,c
所以你可以选择你喜欢的。:)
为了使方法更快,您应该使用成员函数为字符串保留足够的内存reserve
。
您的问题包括两个任务:
第二步可以通过使用 std::string::reserve() 保留一些内存来加速。通常,当重复追加到末尾时,std::string 将不得不多次重新分配内存。如果提前知道结果字符串的大小,则可以避免这种情况。然后可以使用 std::string::reserve() 来告诉 std::string ,这样它就可以减少重新分配内存的调用,这可能会显着提高长字符串的性能。
您始终可以使用以下C
方式:
char outbuf[256];
sprintf(outbuf, "%s,%3.2d,%2.2f,%c", A.c_str(), B, C, D);
请注意,我写的那行非常具体;因为您对双精度、浮点数、字符串长度、...的格式一无所知
在 Visual Studio 2013 下,sprintf 比 ostringstream 快两倍(在发布时测量)。原因可能是因为 ostringstream 做了很多分配,我使用了 _CrtSetAllocHook 并且它在下面的代码示例中被触发了 74 次,而它甚至没有为 sprintf 触发 - 这是在调试中测量的。
附言。stringstream 可以自定义,您可以编写自己的自定义缓冲区,这将是您需要的最佳选择。
#include <Windows.h>
#include <iostream>
#include <sstream>
struct TimeMe {
ULONG64 start;
TimeMe() {
QueryThreadCycleTime(GetCurrentThread(), &start);
}
ULONG64 total() {
ULONG64 end;
QueryThreadCycleTime(GetCurrentThread(), &end);
return (end - start);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
std::string A = "test";
double B = 123.45;
float C = 43.23;
char D = 'c';
char outbuf[256];
std::ostringstream is;
ULONG64 sum=0;
for ( int k = 0; k < 100; ++k ) {
TimeMe me;
// ~8800 ticks
//is.str("");
//is.clear();
//is << A << ',' << B << ',' << C << ',' << D;
//std::string res2 = is.str();
// ~4500 ticks
sprintf(outbuf, "%s,%3.2lf,%2.2f,%c", A.c_str(), B, C, D);
sum += me.total();
}
std::cout << "CPU ticks: " << (sum)/100 << std::endl;
return 0;
}
我认为ostringstream
是一个非常好的方法,“似乎不够快”可能不是那么重要,除非你有很多数字和字符串要处理。
也许[sprintf][1]
http://www.cplusplus.com/reference/cstdio/sprintf/
是一种替代方法,我认为如果您知道结果的长度,这可能会更快:
你new char[length]
在开始时做一个。
例如:
char * buffer = new char[LENGTH];
int a = 1;
double b = 2.0;
string c = "3.0";
int n = sprintf(buffer, "%d plus %f is %s", a, b, c.c_str());
此外,snprintf
建议因为它更安全