2009-05-22 38 views
23

我一直在C++中编写很长一段时间。我总是想知道哪个执行速度更快printfcoutcout或printf两者中哪一个具有更快的执行速度C++?

情况:我正在用C++设计一个应用程序,我有一些限制,比如执行的时间限制。我的应用程序已经在控制台上加载打印命令。那么哪一个更可取printfcout

+0

苹果或橘子:这是美味? – bk1e 2009-05-22 07:31:38

+5

如果对你来说很重要,那就写一个能兼顾时间和空间的小应用程序。这应该需要15分钟的时间才能完成。 – 2009-05-22 07:46:11

+3

@尼尔:它不是那么简单。 std :: cout和operator <<导致在调用时发出更多的代码。所有printf逻辑都位于CRT中,但使用运行时逻辑来解释参数字符串。因此,具有多个呼叫站点和许多不同格式化指令的大型程序可能会看到与小型测试程序不同的效果,只需要一个大的for(很多){printf(“%d”,i); }` – MSalters 2009-05-22 08:29:10

回答

21

每个都有自己的开销。根据您打印的内容,可能会更快。

下面是我想到两点 -

的printf()的解析后,它的“格式化”字符串和行为,这增加了成本。
cout具有更复杂的继承层次结构并传递对象。

实际上,除了最奇怪的情况之外,差异不应该存在。如果你认为它很重要 - 衡量!

编辑 -
哦,哎呀,我不认为我这样做,但为了记录在案,我非常具体的测试条件下,我非常具体的机器和它的非常具体的负载,在编译使用MSVC发布 -

打印150,000“Hello,World!”s(不使用endl)大约需要 -
对于printf()为90ms,对于cout为79ms。

印刷150,000随机双打需要约 -
3450ms为printf(),3420ms为cout。

(平均超过10次)。

的差异是如此渺茫这可能意味着什么......

+1

复杂的继承层次结构和本身传递对象都不会导致开销。 – 2009-05-22 07:06:07

25

你真的需要去关心它具有更快的执行速度?它们都用于简单地将文本输出到控制台/标准输出,这通常不是要求超高效率的任务。对于这个问题,我不会想象在速度上会有很大差异(尽管一个可能预计printf稍微快一点,因为它缺乏面向对象的小复杂性)。然而,鉴于我们正在处理I/O操作,即使是微小的差异也可能会被I/O开销所淹没。当然,如果你比较写入文件的等效方法,情况就是这样。

printf只是将文本输出到标准输出文件的标准方法。
“cout”管道仅仅是将文本输出到标准输出的标准方式。

说完这一切,comp.lang.cc小组讨论了同样的问题。然而,共识确实是因为除了表演以外的原因,你应该选择一个。

6

至少在Windows上,写入控制台是一个巨大的瓶颈,所以“噪声”控制台模式程序将比无声控制台模式程序慢得多。因此,在该平台上,用于处理控制台的库函数的细微差异可能在实践中没有显着差异。

在其他平台上它可能不同。这也取决于你在做什么控制台输出,相对于其他有用的工作。

最后,它取决于您的平台的C和C++ I/O库的实现。

所以这个问题没有一般的答案。

2

实际上我总是发现printf比cout快。但是再一次,cout在类型安全方面为您做了更多的工作。还记得printf是一个简单的函数,而cout是一个基于复杂流层次的对象,所以比较执行时间并不公平。

4

性能是一个无法比较的问题;不能想到它实际计数的任何东西(开发控制台程序)。但是,您应该考虑几点:

  • Iostreams使用运算符链而不是va_args。这意味着你的程序不能崩溃,因为你传递了错误的参数数量。这可能发生在printf上。

  • Iostreams使用运算符重载而不是va_args--这意味着你的程序不能崩溃,因为你传递了一个int并且它期待一个字符串。这可能发生在printf上。

  • Iostreams不支持格式化字符串(这是#1和#2的主要根本原因)。这通常是一件好事,但有时它们很有用。 Boost格式库为那些需要定义行为(抛出异常)而不是未定义行为(如printf情况下)的用户提供Iostreams功能。目前这超出了标准。

  • 与他们的printf equivilants不同,Iostreams可以直接处理可变长度的缓冲区,而不是被迫处理硬编码的cruft。

去找cout。

1

如果你需要找出性能方面的原因,其他东西基本上是错误的与您的应用程序 - 可以考虑使用一些其他的日志记录工具或UI)

-3

你应该从来没有需要问这个问题,因为用户只能读取比他们两个都慢。

如果您需要快速执行,请勿使用。

正如其他人所说的,如果您需要记录操作,请使用某种记录。

2

如果您使用的是C++,则应该使用cout,因为printf属于C系列函数。对于您可能受益的cout有许多改进。至于速度,这不是问题,因为控制台I/O无论如何都会变慢。

2

为了解决这样的:

#include <iostream> 
#include <cstdio> 
#include <ctime> 
using namespace std; 

int main(int argc, char * argcv[]) { 
    const char * const s1 = "some text"; 
    const char * const s2 = "some more text"; 
    int x = 1, y = 2, z = 3; 
    const int BIG = 2000; 
    time_t now = time(0); 
    for (int i = 0; i < BIG; i++) { 
     if (argc == 1) { 
      cout << i << s1 << s2 << x << y << z << "\n"; 
     } 
     else { 
      printf("%d%s%s%d%d%d\n", i, s1, s2, x, y, z); 
     } 
    } 
    cout << (argc == 1 ? "cout " : "printf ") << time(0) - now << endl; 
} 

产生用于cout和printf的相同定时。

-2

轶事证据:
我曾经设计过一个使用ostream操作符的日志类 - 实现速度非常慢(对于大量数据)。

我没有太多分析,所以它可能是由于没有正确使用ostreams,或者仅仅是由于大量的数据记录到磁盘造成的。 (由于性能问题,班级已被报废,实际上printf/fmtmsg风格是首选。)

我同意其他答复,在大多数情况下,这并不重要。如果输出确实是一个问题,您应该考虑避免/延迟它的方法,因为实际的显示更新通常比正确实施的字符串构建花费更多。无论如何,在数毫秒内滚动的数千行信息不是很丰富。

0

在引擎盖下,它们都将使用相同的代码,所以速度差异将无关紧要。

如果你只在Windows上运行,非标准的cprintf()可能会更快,因为它绕过了很多流的​​东西。

然而,这是一个奇怪的要求。没人能快速阅读。为什么不将输出写入文件,那么用户可以在闲暇时浏览文件?

1

我最近在使用CopyFileEx复制文件的窗口上工作的C++控制台应用程序,并将每个副本的“到”和“从”路径回显到控制台,然后在操作结束时显示平均吞吐量。

当我使用printf运行控制台应用程序来回显字符串时,我得到4mb /秒,当用std :: cout替换printf时,吞吐量降至800kb/sec。

我想知道为什么std :: cout调用是如此昂贵,甚至竟然在每个副本上回显出相同的字符串以获得对调用的更好比较。我做了多次运算来平衡比较,但4倍的差异仍然存在。

然后我发现计算器this答案..

的printf和性病::法院接通缓冲标准输出的伎俩,现在我吞吐量数字几乎相同。

我还没有深入了解printf和cout在控制台输出缓冲方面的差异,但是在开始写入控制台之前设置输出缓冲区解决了我的问题。

0

你为什么不去做实验?平均来说,打印字符串helloperson; \ n使用printf平均需要2个时钟滴答,而使用endl的cout需要大量时间 - 1248996720685时钟滴答。将“\ n”作为换行符使用cout只需要41981个时钟刻度。我的代码的短网址低于:

cpp.sh/94qoj

链接可能已经过期。

要回答你的问题,printf会更快。

#include <iostream> 
#include <string> 
#include <ctime> 
#include <stdio.h> 
using namespace std; 
int main() 
{ 
    clock_t one; 
    clock_t two; 
    clock_t averagePrintf; 
    clock_t averageCout; 
    clock_t averagedumbHybrid; 
    for (int j = 0; j < 100; j++) { 
    one = clock(); 
    for (int d = 0; d < 20; d++) { 
     printf("helloperson;"); 
     printf("\n"); 
    } 
    two = clock(); 
    averagePrintf += two-one; 

    one = clock(); 
    for (int d = 0; d < 20; d++) { 
     cout << "helloperson;"; 
     cout << endl; 
    } 
    two = clock(); 
    averageCout += two-one; 

    one = clock(); 
    for (int d = 0; d < 20; d++) { 
     cout << "helloperson;"; 
     cout << "\n"; 
    } 
    two = clock(); 
    averagedumbHybrid += two-one; 
    } 
    averagePrintf /= 100; 
    averageCout /= 100; 
    averagedumbHybrid /= 100; 
    cout << "printf took " << averagePrintf << endl; 
    cout << "cout took " << averageCout << endl; 
    cout << "hybrid took " << averagedumbHybrid << endl; 
} 

是的,我确实使用了dumb这个词。我第一次为自己做了这件事,认为结果很疯狂,所以我搜索了它,最终发布了我的代码。

希望它能帮助, Ndrewffght

相关问题