测试你的电脑一秒能打印多少个数字(printf函数)
1、简介
我们写一个测试程序,来测试下我们的电脑一秒钟可以打印出多少数字。思路很简单,我们只需要利用alarm函数定时1s。然后在while(1)中不断打印变量值就好。
2、代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main()
{
alarm(1); //定时1s
int i = 0;
while(1)
{
printf("%d\n",i++);
}
return 0;
}
这个例子很简单,但是也有很多细节值得我们关注。
3、损耗时间
我们不妨用time来查看下该程序的执行时间:
我们可以发现,这段程序的实际用时为1.003s。但是用户区+内核区的时间为0.061+0.448=0.509s。实际的损耗时间为0.494s。
那么损耗时间究竟损耗在哪儿了呢?其实是损耗在内核区与用户区的频繁切换上了。
程序实际执行时间 = 系统时间 + 用户时间 + 损耗时间
4、printf函数
要想搞明白其时间损耗的本质,我们首先要弄清楚这个printf函数。关于printf函数,我们要知道:
- 调用printf函数是会引起用户区到内核区的切换的;————>因为printf函数是库函数,而且屏幕其实也是文件(linux下一切皆文件),所以printf把数据打印在屏幕上是写文件的过程,底层会调用write函数,每一次printf,都会从用户空间到内核空间的一个切换(或者是用户态到内核态的一个切换),这个是有开销的。
- printf()会把数据先存入缓冲区,然后再打印到屏幕上;
缓冲区什么时候会刷新呢?
(1)缓冲区满
(2)程序结束
(3)强制刷新缓冲区,方法有:\n fflush(stdout);
所以上述程序之所以损耗时间那么久,原因我们就知道了。由于每次打印一个数字都调用\n刷新缓冲区,所以每次打印都会引起用户区到内核区的切换,频繁的切换损耗了程序大量的时间。
5、优化
程序运行时间的瓶颈在于IO,所以我们首选优化IO来优化我们的程序,我们可以不刷新缓冲区,等到缓冲区满再写,所以我们可以用文件重定向,由于文件操作是带缓冲的,所以涉及到用户区到内核区的切换频率大大减少。从而使损耗降低。