为什么printf比stringstream更快还是它?

时间:2009-01-15 01:20:13

标签: c++ c performance

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

9 个答案:

答案 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)

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

答案 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来正是这个原因。