进行以下测试后:
for( i = 0; i < 3000000; i++ ) {
printf( "Test string\n" );
}
for( i = 0; i < 3000000; i++ ) {
write( STDOUT_FILENO, "Test string\n", strlen( "Test string\n" ) );
}
事实证明,对 printf 的调用总共花费了 3 秒,而对 write 的调用则花费了高达 46 秒的时间。如何,通过所有花哨的格式化魔法printf
确实如此,而且事实是printf
本身调用write
, 这可能吗?我缺少什么吗?
任何和所有的想法和意见都会受到赞赏。
鉴于 printf 本身调用 write 这一事实,这怎么可能?我缺少什么吗?
是的,你缺少一些东西。printf
不一定会打电话write
每次。相当,printf
缓冲其输出。也就是说,它经常将其结果存储在内存缓冲区中,仅调用write
当缓冲区已满时,或在某些其他条件下。
write
是一个相当昂贵的调用,比将数据复制到printf
的缓冲区,因此减少了write
调用提供了净性能胜利。
如果您的标准输出定向到终端设备,那么printf
calls write
每次它看到一个\n
——就你而言,每次被调用时。如果您的标准输出定向到一个文件(或/dev/null
), then printf
仅当其内部缓冲区已满时才调用 write。
假设您正在重定向输出,并且printf
的内部缓冲区是4Kbytes,然后第一个循环调用write
3000000 / (4096 / 12) == 8780 次。然而,你的第二个循环调用write
300万次。
除了减少呼叫次数的影响之外write
, 是个size的来电write
。硬盘驱动器中的存储量是一个扇区——通常为 512 字节。写入比扇区更少量的数据可能涉及读取扇区中的原始数据、修改它,并将结果写回。调用write
然而,使用完整的扇区可能会更快,因为您不必读入原始数据。printf
的缓冲区大小选择为典型扇区大小的倍数。这样系统就可以最有效地将数据写入磁盘。
我希望你的第一个循环比第二个循环快得多。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)