C++:cout 语句是否会使代码变慢
C++: Does cout statement makes code slower
我正在从文件中读取大约 300 万行并将它们插入到 STL 映射中。因此,在我的 while 循环中,我从文件中读取每一行,我还通过一个简单的 cout 语句打印到控制台它是什么行号。我的一位朋友最近指出,这会使代码变慢。我想知道这是否属实,如果是为什么?
如前所述,写入终端几乎肯定会变慢。为什么?
-
根据您的操作系统,
std::cout
可能会使用线路缓冲 - 这意味着每条线路可能会单独发送到终端程序。 当您使用std::endl
而不是 '' 时,它肯定会刷新缓冲区。 将数据写入较小的块意味着额外的系统调用和渲染工作,这会显着减慢速度。 -
一些操作系统/编译器甚至更慢 - 例如,Visual C++:https://connect.microsoft.com/VisualStudio/feedback/details/642876/std-wcout-is-ten-times-slower-than-wprintf-performance-bug-in-c-library
-
显示输出的终端需要调用以清除现有屏幕内容,渲染字体,更新滚动条,将行复制到历史记录/缓冲区中。 特别是当他们以小块的形式获得新内容时,他们无法可靠地猜测他们需要等待多长时间,并且可能会尝试更新屏幕以获取他们收到的一点点:这是昂贵的,也是过度刷新或无缓冲输出缓慢的原因。
-
一些终端提供"跳转滚动"选项,这意味着如果他们发现他们落后 10 页,他们会立即渲染最后一页,而前 9 页的内容永远不会出现在屏幕上:这可能很好而且很快。 尽管如此,"跳转滚动"并不总是被使用或想要的,因为这意味着输出永远不会呈现给最终用户的眼睛:也许该程序在某些情况下是为了打印一个巨大的红色错误消息 - 使用跳转滚动甚至不会闪烁来吸引用户的注意力,但如果没有跳转滚动,您可能会注意到它。
-
当我在彭博社工作时,我们有源源不断的日志文件更新,占用了几个显示器 - 有时显示的输出会落后几分钟;从默认的 Solaris xterm 切换到 rxvt 可确保它始终跟上步伐
-
-
将输出重定向到/dev/null 是查看特定终端减慢速度的好方法
如前所述,写入终端几乎肯定会变慢。为什么?
- 缓冲:
写入终端默认使用 line buffering
*。这意味着每次遇到换行符时都会传输缓冲区的内容。写入文件时,仅当缓冲区已满或手动刷新流时,才会刷新缓冲区。这是造成差异的主要原因,因为 I/O 操作的数量明显不同。
*:对于Unix实现来说,这是正确的,但其他实现可能是无缓冲的(参见评论中的讨论)。
- 渲染:
当您写入终端时,这涉及在屏幕上呈现,并且根据终端的不同,可能涉及其他操作,这些操作可能会减慢程序速度(并非所有终端都相同,您可能会发现速度显着差异只是切换到不同的终端)。
这几乎可以肯定是真的。 写信到终端是臭名昭著的减慢速度。 运行程序并将输出重定向到文件,看看它的速度有多快。 然后完全取出输出语句并再次测量。 您将立即看到该行为。
这是一个脑残的例子:
#include <stdio.h>
int main(void)
{
int i;
for (i = 0; i < 10000; i++)
{
printf("Hello, world!n");
}
return 0;
}
我构建了这个未优化的程序并运行了它,一次输出到终端,一次输出到文件。 终端输出的结果:
real 0m0.026s
user 0m0.003s
sys 0m0.007s
重定向 I/O 的结果:
real 0m0.003s
user 0m0.001s
sys 0m0.001s
你去吧,~8 倍快。 这是针对极少数印刷品!
- 此代码是否违反一个定义规则
- C++ LeetCode #377 的 DP 解决方案中,此代码是否有错误?
- 在cpp中使用boost-python的python代码是否进行动态内存分配
- 使用全局 IP 地址时,C++ winsock 2 应用程序中的代码是否必须更改?
- 以下代码是否存在内存泄漏?
- 如何判断我正在运行的Microsoft C++代码是否使用 /EHa 开关编译?
- 我的选择排序代码是否存在导致它跳过数组中的元素的问题?
- 代码是否有效.如果我想显示第一个元素?如果不是,那么 s.begin() 会返回什么?
- C++模板的对象代码是否在可执行文件和动态库中重复?
- 任何人都可以检查这个回文 c++ 代码是否正确
- Android Studio 项目中的 c++ 代码是否最终出现在 apk 文件中(除了 .so 文件)
- 此代码是否容易受到 SQL 注入的攻击?我该如何使其安全
- 使用 log4cplus 将日志发送到远程系统日志服务器的代码是否正确
- 代码是否交换数组的两个数字
- 如何检查编译的代码是否使用了 SSE 和 AVX 指令?
- 此代码是否有逻辑错误
- 使用 char16_t 类型作为 char[] 数组,并通过 reinterpret_cast<> 重新转换它。我的代码是否有未定义的行为?
- GPU cuda 代码是否适用于多个 GPU 卡而无需任何实现
- 此代码是否对C++线程安全
- QaudioOutput代码是否有任何内存泄漏