c - printf 减慢了我的程序

标签 c performance linux-kernel stdout glibc

我有一个小的 C 程序来计算哈希值(用于哈希表)。我希望代码看起来很干净,但有一些与它无关的东西困扰着我。

我可以在大约 0.2-0.3 秒内轻松生成大约一百万个哈希值(以/usr/bin/time 为基准)。但是,当我在 for 循环中使用 printf() 时,程序会减慢到大约 5 秒。

  1. 这是为什么?
  2. 如何让它更快? mmapp() 可能是标准输出?
  3. stdlibc 在这方面是如何设计的,如何改进?
  4. 内核如何更好地支持它?需要如何修改才能使本地"file"(套接字、管道等)的吞吐量真正变快?

我期待有趣和详细的回复。谢谢。

PS:这是一个编译器构建工具集,所以不要害羞地进入细节。虽然这与问题本身无关,但我只是想指出我感兴趣的细节。

附录

我正在寻找解决方案和解释的更多程序化方法。确实,管道可以完成这项工作,但我无法控制“用户”的操作。

当然,我现在正在进行测试,“普通用户”不会这样做。但这并没有改变一个简单的 printf() 会减慢进程的事实,这是我试图找到最佳编程解决方案的问题。


附录 - 惊人的结果

引用时间是针对 TTY 内的普通 printf() 调用,大约需要 4 分 20 秒。

在/dev/pts(例如 Konsole)下测试可将输出加速到大约 5 秒。

在我的测试代码中使用 setbuffer() 到大小为 16384 所花费的时间与 8192 几乎相同:大约 6 秒。

setbuffer() 在使用时显然没有影响:它花费相同的时间(在 TTY 上大约 4 分钟,在 PTS 上大约 5 秒)。

令人惊讶的是,如果我在 TTY1 上开始测试然后切换到另一个 TTY,它确实与 PTS 上的测试一样:大约5 秒。

结论:内核做了一些与可访问性和用户友好性有关的事情。哼!

通常,无论您是在 TTY 处于事件状态时盯着它看,还是切换到另一个 TTY,它都应该同样慢。


教训:运行输出密集型程序时,切换到另一个TTY!

最佳答案

无缓冲的输出非常慢。

默认情况下 stdout 是全缓冲的,但是当连接到终端时,stdout 是无缓冲的或行缓冲的。

尝试使用 setvbuf() 打开 stdout 的缓冲,如下所示:

char buffer[8192];

setvbuf(stdout, buffer, _IOFBF, sizeof(buffer));

关于c - printf 减慢了我的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1832489/

相关文章:

代码打印额外的内存垃圾

html - 如果大于 1px,html 中的重复背景是否更有效?

linux-kernel - 用户空间和内核线程之间的共享内存

C 指针 : pointing to an array of fixed size

c - 通过 Julia 的 C 接口(interface)为 `*x` 赋值

mysql - 将 S3 数据加载到 Aurora MySQL 实例中

java - 使用 Jsch 生成 4096 位 RSA key 比 2048 位慢得多

linux - Linux内核中哪些内核线程负责发送网络数据包

c - 为什么在中断处理程序中使用自旋锁

c - 如何在不关闭套接字的情况下向主机发送 FIN 标志