为什么snprintf比ostringstream更快还是它?

我在某处读到snprintf比ostringstream更快。 有没有人有这方面的经验? 如果是,为什么它更快。

我们用sprintf(使用静态分配的缓冲区)替换了内部循环中的一些字符串流,这在msvc和gcc中都有很大的不同。 我想这个代码的动态内存管理:

 {
   char buf [100];
   int i = 100;
   sprintf(buf,“%d”,i);
   //用buf做点什么
 }

比…简单得多

 {
   std :: stringstream ss;
   int i = 100;
   ss << i;
   std :: string s = ss.str();
   //用s做点什么
 }

但我对stringstreams的整体表现非常满意。

有些人可能会告诉你,这些function不能比彼此快,但是它们的实现可以。 那是对的,我想我会同意的。

您不太可能注意到基准以外的其他差异。 c ++流通常趋于缓慢的原因是它们更灵活。 灵活性通常以时间或代码增长为代价。

在这种情况下,C ++流基于流缓冲区。 流本身只是保持格式化和错误标志的船体,并调用c ++标准库的正确i/o方面(例如,num_put打印数字),将值格式良好的打印输出到连接到c ++流的基础流缓冲区。

所有这些机制 – 方面和缓冲区都是由虚函数实现的。 虽然确实没有标记注释,但这些函数必须实现为比c stdio pendant更慢 ,事实上它们会比通常使用c stdio函数慢一些(我在一段时间之前使用gcc / libstdc ++进行基准测试,实际上已经注意到了减速 – 但你在日常使用中几乎没有注意到)。

绝对这是特定于实现的。

但如果您真的想知道,请编写两个小程序,并进行比较。 您需要包含您所考虑的典型用法,两个程序需要生成相同的字符串,并且您将使用分析器来查看时序信息。

那你就知道了。

一个问题可能是ostringstream添加的类型安全带来了额外的开销。 不过,我没有做过任何测量。

正如litb所说 ,标准流支持许多我们并不总是需要的东西。 一些流实现摆脱了这种从未使用过的灵活性,例如参见FAStream 。

很有可能因为sprintf是用汇编编写的CRT的一部分。 ostringstream是STL的一部分,可能更一般地编写,并且具有OOP代码/开销来处理。

是的,如果使用Visual C ++ 5.0在几百万个数字上运行下面的函数,第一个版本大约需要两倍于第二个版本,并产生相同的输出。

将紧密循环编译成.exe并运行Windows timethis something.exe' or the Linux time something’是我如何调查我的大部分性能好奇心。 (`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 } 

我知道printf系列函数比相应的C ++函数(cout,cin和其他流)更快的一个原因是后者做了类型检查。 由于这通常涉及对重载运算符的一些请求,因此可能需要一些时间。

事实上,在编程竞赛中,通常建议你使用printf等而不是cout / cin来正是这个原因。