cout 或 printf 两者中哪一个执行速度更快 C++?

发布于 2024-07-21 13:45:34 字数 207 浏览 4 评论 0原文

我已经用 C++ 编写代码很长时间了。 我一直想知道printfcout哪个执行速度更快?

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

I have been coding in C++ for a long time. I always wondered which has a faster execution speed printf or cout?

Situation: I am designing an application in C++ and I have certain constraints such as time limit for execution. My application has loads printing commands on the console. So which one would be preferable printf or cout?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

影子是时光的心 2024-07-28 13:45:34

每个都有自己的管理费用。 根据您打印的内容,两者都可能更快。

这里有两点 -

printf() 必须解析“格式”字符串并对其进行操作,这会增加成本。
cout 具有更复杂的继承层次结构并传递对象。

实际上,除了最奇怪的情况外,这种差异对所有情况都不重要。 如果您认为这真的很重要 - 衡量!

编辑 -
哦,哎呀,我不相信我正在这样做,但为了记录,在我非常具体的测试用例上,使用我非常具体的机器及其非常具体的负载,使用 MSVC 在发行版中进行编译 -

打印 150,000 “Hello, World !"s(不使用 endl)大约需要 -
printf() 需要 90 毫秒,cout 需要 79 毫秒。

打印 150,000 个随机双精度数大约需要 -
printf() 为 3450 毫秒,cout 为 3420 毫秒。

(平均超过 10 次运行)。

差异如此之小,可能没有任何意义......

Each has its own overheads. Depending on what you print, either may be faster.

Here are two points that come to mind -

printf() has to parse the "format" string and act upon it, which adds a cost.
cout has a more complex inheritance hierarchy and passes around objects.

In practice, the difference shouldn't matter for all but the weirdest cases. If you think it really matters - measure!

EDIT -
Oh, heck, I don't believe I'm doing this, but for the record, on my very specific test case, with my very specific machine and its very specific load, compiling in Release using MSVC -

Printing 150,000 "Hello, World!"s (without using endl) takes about -
90ms for printf(), 79ms for cout.

Printing 150,000 random doubles takes about -
3450ms for printf(), 3420ms for cout.

(averaged over 10 runs).

The differences are so slim this probably means nothing...

演多会厌 2024-07-28 13:45:34

性能不是比较的问题; 想不出任何真正重要的东西(开发控制台程序)。 但是,您应该考虑以下几点:

  • Iostream 使用运算符链接而不是 va_args。 这意味着您的程序不会因为传递了错误数量的参数而崩溃。 printf 可能会发生这种情况。

  • Iostreams 使用运算符重载而不是 va_args ——这意味着您的程序不会崩溃,因为您传递了一个 int 而它需要一个字符串。 printf 可能会发生这种情况。

  • Iostream 没有对格式字符串的本机支持(这是 #1 和 #2 的主要原因)。 这通常是一件好事,但有时它们很有用。 Boost 格式库将此功能引入 Iostreams,供那些需要定义行为(引发异常)而不是未定义行为(如 printf 的情况)的人使用。 目前这不符合标准。

  • Iostream 与 printf 等价物不同,可以直接自行处理可变长度缓冲区,而不必被迫处理硬编码的残骸。

    Iostream 与 printf 等价物不同,可以直接自行

去cout吧。

Performance is a non-issue for comparison; can't think of anything where it actually counts (developing a console-program). However, there's a few points you should take into account:

  • Iostreams use operator chaining instead of va_args. This means that your program can't crash because you passed the wrong number of arguments. This can happen with printf.

  • Iostreams use operator overloading instead of va_args -- this means your program can't crash because you passed an int and it was expecting a string. This can happen with printf.

  • Iostreams don't have native support for format strings (which is the major root cause of #1 and #2). This is generally a good thing, but sometimes they're useful. The Boost format library brings this functionality to Iostreams for those who need it with defined behavior (throws an exception) rather than undefined behavior (as is the case with printf). This currently falls outside the standard.

  • Iostreams, unlike their printf equivilants, can handle variable length buffers directly themselves instead of you being forced to deal with hardcoded cruft.

Go for cout.

佞臣 2024-07-28 13:45:34

您真的需要关心哪个执行速度更快吗? 它们都仅用于将文本打印到控制台/标准输出,这通常不是一项需要超高效率的任务。 就这一点而言,我不认为速度会有很大差异(尽管人们可能期望printf稍微快一点,因为它缺乏对象的小复杂性- 导向性)。 然而,考虑到我们在这里处理 I/O 操作,即使是很小的差异也可能会被 I/O 开销所淹没。 当然,如果您比较写入文件的等效方法,情况就是如此。

printf 只是 C 语言中将文本输出到 stdout 的标准方法。
“cout”管道只是 C++ 中将文本输出到 stdout 的标准方法。

综上所述,comp.lang 上有一个线程.cc 小组讨论同一问题。 然而,共识似乎是您应该出于性能以外的原因选择其中之一。

Do you really need to care which has a faster execution speed? They are both used simply for printing text to the console/stdout, which typically isn't a task that demands ultra-high effiency. For that matter, I wouldn't imagine there to be a large difference in speed anyway (though one might expect printf to be marginally quicker because it lacks the minor complications of object-orientedness). Yet given that we're dealing with I/O operations here, even a minor difference would probably be swamped by the I/O overhead. Certainly, if you compared the equivalent methods for writing to files, that would be the case.

printf is simply the standard way to output text to stdout in C.
'cout' piping is simply the standard way to output text to stdout in C++.

Saying all this, there is a thread on the comp.lang.cc group discussing the same issue. Consensus does however seem to be that you should choose one over the other for reasons other than performance.

靑春怀旧 2024-07-28 13:45:34

C++ cout 速度慢的原因是默认与 stdio 同步。

尝试执行以下命令来解决此问题。

ios_base::sync_with_stdio(false)

http://www.ios_base::sync_with_stdio (false) cplusplus.com/reference/iostream/ios_base/sync_with_stdio/

http:// /msdn.microsoft.com/es-es/library/7yxhba01.aspx

The reason C++ cout is slow is the default sync with stdio.

Try executing the following to deactivate this issue.

ios_base::sync_with_stdio(false)

http://www.cplusplus.com/reference/iostream/ios_base/sync_with_stdio/

http://msdn.microsoft.com/es-es/library/7yxhba01.aspx

夏の忆 2024-07-28 13:45:34

至少在 Windows 上,写入控制台是一个巨大的瓶颈,因此“嘈杂”的控制台模式程序将比安静的程序慢得多。 因此,在该平台上,用于处理控制台的库函数的细微差异在实践中可能不会产生重大差异。

在其他平台上可能会有所不同。 它还取决于您正在执行多少控制台输出(相对于其他有用的工作)。

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

所以这个问题没有通用的答案。

On Windows at least, writing to the console is a huge bottleneck, so a "noisy" console mode program will be far slower than a silent one. So on that platform, slight differences in the library functions used to address the console will probably make no significant difference in practice.

On other platforms it may be different. Also it depends just how much console output you are doing, relative to other useful work.

Finally, it depends on your platform's implementation of the C and C++ I/O libraries.

So there is no general answer to this question.

花开浅夏 2024-07-28 13:45:34

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

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

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

然后我在 stackoverflow 上找到了这个答案..

打开标准输出的缓冲成功了,现在 printf 和 std::cout 的吞吐量数字几乎相同。

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

I recently was working on a C++ console application on windows that copied files using CopyFileEx and was echoing the 'to' and 'from' paths to the console for each copy and then displaying the average throughput at the end of the operation.

When I ran the console application using printf to echo out the strings I was getting 4mb/sec, when replacing the printf with std::cout the throughput dropped to 800kb/sec.

I was wondering why the std::cout call was so much more expensive and even went so far as to echo out the same string on each copy to get a better comparison on the calls. I did multiple runs to even out the comparison, but the 4x difference persisted.

Then I found this answer on stackoverflow..

Switching on buffering for stdout did the trick, now my throughput numbers for printf and std::cout are pretty much the same.

I have not dug any deeper into how printf and cout differ in console output buffering, but setting the output buffer before I begin writing to the console solved my problem.

疑心病 2024-07-28 13:45:34

你为什么不做个实验呢? 对我来说,平均打印字符串 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;
}

是的,我确实用了“愚蠢”这个词。 我首先自己做的,认为结果很疯狂,所以我搜索了它,最终发布了我的代码。

希望能帮助到你,
恩德鲁夫特

Why don't you do an experiment? On average for me, printing the string helloperson;\n using printf takes, on average, 2 clock ticks, while cout using endl takes a huge amount of time - 1248996720685 clock ticks. Using cout with "\n" as the newline takes only 41981 clock ticks. The short URL for my code is below:

cpp.sh/94qoj

link may have expired.

To answer your question, printf is faster.

#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;
}

Yes, I did use the word dumb. I first made it for myself, thinking that the results were crazy, so I searched it up, which ended up with me posting my code.

Hope it helps,
Ndrewffght

自控 2024-07-28 13:45:34

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

If you're using C++, you should use cout instead as printf belongs to the C family of functions. There are many improvements made for cout that you may benefit from. As for speed, it isn't an issue as console I/O is going to be slow anyway.

夜声 2024-07-28 13:45:34

另一个 Stack Overflow 问题涉及 C 风格格式化 I/O 与 C++ iostream 的相对速度:

但请注意,所讨论的基准测试是针对格式化内存缓冲区的。 我猜想,如果您实际上对控制台或文件执行 I/O,由于 I/O 占用了更多的总时间,相对速度差异会小得多。

Another Stack Overflow question addressed the relative speed of C-style formatted I/O vs. C++ iostreams:

Note, however, that the benchmarks discussed were for formatting to memory buffers. I'd guess that if you're actually performing the I/O to a console or file that the relative speed differences would be much smaller due to the I/O taking more of the overall time.

黯然#的苍凉 2024-07-28 13:45:34

实际上,我一直发现 printf 比 cout 更快。 但话又说回来,cout 在类型安全方面为您做了更多的事情。 另请记住 printf 是一个简单的函数,而 cout 是一个基于复杂流层次结构的对象,因此比较执行时间并不公平。

In practical terms I have always found printf to be faster than cout. But then again, cout does a lot more for you in terms of type safety. Also remember printf is a simple function whereas cout is an object based on a complex streams hierarchy, so it's not really fair to compare execution times.

岁月静好 2024-07-28 13:45:34

要解决这个问题:

#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 生成相同的时序。

To settle this:

#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;
}

produces identical timings for cout and printf.

梦中楼上月下 2024-07-28 13:45:34

如果出于性能原因您需要找出您的应用程序存在其他根本性错误 - 请考虑使用其他日志记录工具或 UI ;)

If you ever need to find out for performance reasons, something else is fundamentally wrong with your application - consider using some other logging facility or UI ;)

奢华的一滴泪 2024-07-28 13:45:34

它取决于多种因素,例如实现、cout 是否与底层 C 流和输入同步,但通常 printf 更快。 以下是一些根本原因(来自 https://stackoverflow.com/a/65325727/471164):

  • 共享格式化状态:每个格式化输出操作都必须检查之前可能已被 I/O 操纵器改变的所有格式化状态。 因此,iostream 本质上比类似 printf 的 API 慢(尤其是使用 Rust 或 {fmt} 避免解析开销),其中所有格式信息都是本地的。

  • 低效的顶级 API:使用 iostream 格式化消息通常包含多个格式化函数调用,因为参数和 I/O 操纵器与消息的各个部分交错。 例如,

    中有三个这样的调用(godbolt

    std::cout <<   “答案是”<<   回答<<   ".\n"; 
      

    与等效 printf 调用中的一个 (godbolt) 相比:

    printf("答案是 %d.\n", answer); 
      

    每个格式化函数调用都会产生大量开销(见上文)。 在基于替换的 API(例如 printf)中,字符串文字部分的开销很小。

  • 额外缓冲和同步。 可以使用 sync_with_stdio(false) 禁用此功能,但代价是与其他 I/O 设施的互操作性较差。

也就是说 printf 也不是特别快,您可能需要考虑使用 C++23 std::print{fmt}库,它基于。

It depends on multiple factors such as implementation, whether cout is synchronized with the underlying C stream and input but generally printf is faster. Here are some fundamental reasons why (from https://stackoverflow.com/a/65325727/471164):

  • Shared formatting state: every formatted output operation has to check all formatting state that might have been previously mutated by I/O manipulators. For this reason iostreams are inherently slower than printf-like APIs (especially with format string compilation like in Rust or {fmt} that avoid parsing overhead) where all formatting information is local.

  • Inefficient top-level API: formatting a message with iostreams normally consists of multiple formatting function calls because arguments and I/O manipulators are interleaved with parts of the message. For example, there are three such calls (godbolt) in

    std::cout << "The answer is " << answer << ".\n";
    

    compared to just one (godbolt) in the equivalent printf call:

    printf("The answer is %d.\n", answer);
    

    Each of these formatting function invocations has substantial overhead (see above). In replacement-based APIs like printf there is little overhead for literal portions of the string.

  • Extra buffering and synchronization. This can be disabled with sync_with_stdio(false) at the cost of poor interoperability with other I/O facilities.

That said printf is not particularly fast either and you might want to consider using C++23 std::print or the {fmt} library, it is based on.

猫瑾少女 2024-07-28 13:45:34

在底层,它们都将使用相同的代码,因此速度差异并不重要。

如果您仅在 Windows 上运行,非标准 cprintf() 可能会更快,因为它绕过了许多流内容。

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

Under the hood, they will both use the same code, so speed differences will not matter.

If you are running on Windows only, the non-standard cprintf() might be faster as it bypasses a lot of the streams stuff.

However it is an odd requirement. Nobody can read that fast. Why not write output to a file, then the user can browse the file at their leisure?

输什么也不输骨气 2024-07-28 13:45:34

您应该永远不需要问这个问题,因为用户只能比他们两个阅读得慢。

如果您需要快速执行,请不要使用其中任何一个。

正如其他人提到的,如果您需要操作记录,请使用某种日志记录。

You should never need to ask this question, as the user will only be able to read slower than both of them.

If you need fast execution, don't use either.

As others have mentioned, use some kind of logging if you need a record of the operations.

半步萧音过轻尘 2024-07-28 13:45:34

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

我没有对此进行太多分析,因此这可能是由于未正确使用 ostreams 造成的,或者仅仅是由于记录到磁盘的数据量所致。 (由于性能问题,该课程已被废弃,实际上 printf / fmtmsg 风格是首选。)

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

Anecdotical evidence:
I've once designed a logging class to use ostream operators - the implementation was insanely slow (for huge amounts of data).

I didn't analyze that to much, so it might as well have been caused by not using ostreams correctly, or simply due to the amount of data logged to disk. (The class has been scrapped because of the performance problems and in practice printf / fmtmsg style was preferred.)

I agree with the other replies that in most cases, it doesn't matter. If output really is a problem, you should consider ways to avoid / delay it, as the actual display updates typically cost more than a correctly implemented string build. Thousands of lines scrolling by within milliseconds isn't very informative anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文