[英]C: Why is a fprintf(stdout,…) so slow?
我仍然经常使用控制台输出来获取我的代码中发生的事情。 我知道这可能有点老式,但我也用它来“管道”stdout到日志文件等。
但是,事实证明,由于某种原因,控制台的输出速度变慢了。 我想知道是否有人可以解释为什么fprintf()到控制台窗口似乎有点阻塞。
到目前为止我做过/诊断过的事情:
我测量了一个简单的fprintf(stdout,"quick fprintf\\n");
它需要:0.82ms(平均)。 这被认为是太久了,因为vsprintf_s(...)
在几微秒内将相同的输出写入字符串。 因此,必须有一些特定的阻止控制台。
为了摆脱阻塞,我使用了vsprintf_s(...)
将我的输出复制到一个类似于fifo的数据结构中。 数据结构受临界区对象的保护。 然后,单独的线程通过将排队的输出放入控制台来对数据结构进行取消。
我可以通过引入管道服务获得进一步的改进。 我的程序的输出(应该最终在控制台窗口中)按以下方式进行:
vsprintf_s(...)
将输出格式化为简单字符串。 fprintf(stdout,...)
将数据结构出列到控制台。 所以我有两个进程,每个进程至少有两个线程,它们之间有一个命名管道,管道两侧有类似数据结构,以避免在管道缓冲区满时阻塞。
这是很多东西,以确保控制台输出是“非阻塞”。 但结果并不算太糟糕。 我的主程序可以在几微秒内编写复杂的fprintf(stdout,...)。
也许我之前应该问过:还有其他(更容易!)的方式来获得非阻塞控制台输出吗?
我认为时间问题与控制台默认为线缓冲这一事实有关。 这意味着每次向它写一个'\\n'
字符时,整个输出缓冲区就会被发送到控制台,这是一个相当昂贵的操作。 这是您为直接在输出中显示的行支付的价格。
您可以通过将缓冲策略更改为完全缓冲来更改此默认行为。 结果是输出将以等于缓冲区大小的块发送到控制台,但单个操作将更快完成。
在第一次写入控制台之前进行此调用:
char buf[10000];
setvbuf(stdout, buf, _IOFBF, sizeof(buf));
单个写入的时间应该会改善,但输出不会立即出现在控制台中。 这对于调试来说不太有用,但时间会有所改善。 如果你设置一个以固定时间间隔调用fflush(stdout)
的线程,比如每秒一次,你应该在个别写入的性能和编写输出的程序之间的延迟和你可以的时间之间得到合理的平衡。实际上在控制台上看到它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.