我在某处读到sprintf比stringstream快。有没有人有过这方面的经验?如果是,为什么它会更快。
答案 0 :(得分:25)
std::ostringstream
不是必需更慢,但实施时通常会更慢。 FastFormat's website has some benchmarks
流的标准库设计比snprintf
支持的要多得多。该设计旨在是可扩展的,并包括由公开的方法调用的protected
virtual
方法。这允许您从其中一个流类派生,并确保如果重载protect
ed方法,您将获得所需的行为。我相信编译器可以避免virtual
函数调用的开销,但我不知道有任何编译器。
此外,流操作通常在内部使用可增长的缓冲区;这意味着内存分配相对较慢。
答案 1 :(得分:9)
我们用sprintf(使用静态分配的缓冲区)替换了内部循环中的一些字符串流,这在msvc和gcc中都有很大的不同。我想这个代码的动态内存管理:
{ char buf[100]; int i = 100; sprintf(buf, "%d", i); // do something with buf }
比
简单得多{ std::stringstream ss; int i = 100; ss << i; std::string s = ss.str(); // do something with s }
但我对stringstreams的整体表现非常满意。
答案 2 :(得分:8)
有些人可能会告诉你,这些功能不能比彼此快,但是它们的实现可以。那是对的,我想我会同意的。
你不太可能注意到基准以外的其他差异。 c ++流通常趋于更慢的原因是它们更灵活。灵活性通常以时间或代码增长为代价。
在这种情况下,C ++流基于流缓冲区。流本身只是保持格式化和错误标志的船体,并调用c ++标准库的正确i/o
方面(例如,num_put打印数字),打印值,格式良好,到连接到c ++流的底层流缓冲区。
所有这些机制 - 方面和缓冲区都是由虚函数实现的。虽然确实没有标记 note,但这些函数必须实现为比c stdio pendants 慢,这一事实会使它们比正常使用c stdio函数慢一些(我在前一段时间的基准测试) gcc / libstdc ++实际上注意到了一个减速 - 但你在日常使用中几乎没有注意到这一点。
答案 3 :(得分:3)
这绝对是特定于实现的。
但如果您真的想知道,请编写两个小程序,并进行比较。您需要包含您所考虑的典型用法,两个程序需要生成相同的字符串,并且您将使用分析器来查看时间信息。
那你就知道了。
答案 4 :(得分:1)
一个问题可能是ostringstream
添加的类型安全带来了额外的开销。但是,我没有做过任何测量。
答案 5 :(得分:0)
很有可能因为sprintf
是用汇编编写的CRT的一部分。 ostringstream
是STL的一部分,可能更一般地编写,并且有OOP代码/开销来处理。
答案 6 :(得分:0)
答案 7 :(得分:0)
是的,如果你使用Visual C ++ 5.0在几百万个数字上运行下面的函数,第一个版本大约需要两倍于第二个版本,并产生相同的输出。
将紧密循环编译成.exe并运行Windows timethis something.exe' or the Linux
时间'是我调查大部分性能好奇心的方法。 (`timethis'可以在网上找到)
void Hex32Bit(unsigned int n, string &result)
{
#if 0
stringstream ss;
ss
<< hex
<< setfill('0')
<< "0x" << setw(8) << n
;
result = ss.str();
#else
const size_t len = 11;
char temp[len];
_snprintf(temp, len, "0x%08x", n);
temp[len - 1] = '\0';
result = temp;
#endif
}
答案 8 :(得分:-1)
我知道printf系列函数比相应的C ++函数(cout,cin和其他流)更快的一个原因是后者做了类型检查。由于这通常涉及对重载运算符的一些请求,因此可能需要一些时间。
事实上,在编程比赛中,通常建议你使用printf等而不是cout / cin来正是这个原因。