我有一个小的C程序用于计算哈希(用于哈希表)。代码看起来相当干净,但有一些与之无关的问题困扰着我。
我可以在约0.2-0.3秒内轻松生成大约100万个哈希值(使用/usr/bin/time进行基准测试)。然而,当我在for循环中使用printf()打印它们时,程序会变慢,大约需要5秒钟。
- 为什么会这样?
- 如何使它更快?可能是mmapp() stdout?
- stdlibc在这方面的设计如何,如何改进?
- 内核如何更好地支持它?需要如何修改才能使本地“文件”(套接字、管道等)的吞吐量真正快速?
我期待有趣和详细的回复。谢谢。
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!
memmove
操作。请注意,此处提到的“memmove”是一种内存操作函数。 - caf