javadrawstring设置字符大小_Java缓冲流设置8192和10000的性能竟然相差这么大

背景

前段时间在同事提交的代码中看到这样一段代码,非常简单,就是通过BufferedReader缓冲区模式读磁盘文件的代码,缓冲区的大小设置为10000。

9b11bb94df6a69b10805e1dfd6d3eb89.png

原理简介

在我的印象中,很少有自己去设置缓冲区大小的,都是使用默认的缓冲区大小。而通过JDK的IO流源码可以发现,缓冲区的默认大小是8192个字符,一个字符是2个字节,所以JAVA IO流的默认缓存区大小是16384个字节即2的14次方。注意:设置缓冲区的大小不要随便设置,要么就设置成8192的整数倍,要么就用默认值。

实际上,从磁盘读取的数据会保存到Page Cache中,Page Cache的中文译名叫页高速缓存,是Linux内核使用的磁盘高速缓存,是一个纯内存的工作组件,它的作用就是为比较慢的磁盘进行加速。如果要访问的文件块正好位于Page Cache内,那么不会发生磁盘IO;否则会发生缺页中断,并用从磁盘读取到的块内容来填充它 。MMAP内存映射文件的零拷贝技术就是访问的数据不需要在page cache和用户缓冲区之间进行拷贝。

Page Cache以页为单位,Linux页大小一般是4KB,而文件系统以块为单位进行管理,一般一个块的大小默认是4KB。通常情况下,磁盘的扇区为512字节,因此一个磁盘块包含8个扇区。

极端情况下讨论,便于理解:假如文件大小是16384 * 2个字节。一次磁盘IO就是读取一个磁盘块的内容,JAVA IO流默认的缓存区大小是16384个字节,相当于读取4次磁盘块的内容刚好填充满,按照JDK默认值读完整个文件需要8次磁盘IO。如果将缓冲区的大小设置为10000即20000个字节要读取5次磁盘块的内容,而第5次的内容会多出,即前5次磁盘IO读取了20000个字节,还剩下12768个字节,一次磁盘IO是4096个字节,这里需要4次磁盘IO,因此当设置为10000时,总共需要9次磁盘IO。

性能测试

还是通过JMH基准测试工具进行测试,预热一轮,迭代一轮,读取的文件大小一样,都是123MB,测试代码如下:

4f0359412237b524e88c4490faf1257c.png

测试结果

缓冲区设置为10000的耗时330.853毫秒,设置为8192的耗时261.777毫秒,性能差不多提升了26%。

28d4f02ca0c50ecb4fbd9a4dbb1e8a42.png
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值