为什么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来正是这个原因。