IO是如何利用缓冲区来搞高性能的,原理是什么?

我知道有种说法,很笼统。比如读缓冲时,如果没有缓冲区,CPU就总是在一次次的读,如果有了,可以一次性读取,这样节省时间。
这样的回答我不明白。这个CPU的节省又不是给我的这个程序节省的,大不了操作系统可以多用一些CPU干别的了。对于我的程序来说,我一次次的读,和等着数据进入缓冲区再一次性的读,在时间上根本没有分别呀。
以上是我的理解,大家都是怎么认识缓冲区的。
[b]问题补充:[/b]
说的得,我的程序还真是单线程的。
我为了读某一个流,不可能在不频繁的情况下再起一个线程。
我想大家都还不有仔细看我的问题。请不要在不仔细看问题的情况下就臆断问题。
我要的是原理的解释,不是说你告诉我缓存好用。
[b]问题补充:[/b]
ych19850810老兄说的不是Java IO的缓冲原理。

不管是不是单线程,两种IO读取方式的性能有很大差别,这个现象在CPU主频越低时(或文件很大时)越明显看得出来,就像有一堆石头100块,有两个走路很慢的人去搬运,一个每次搬50块,一个一次搬一块,前面那个2次搬完,后面这个即要搬100次;我曾帮同事调个android手机上读取文件的性能,就发现。现在的外设控制器都有自己的缓冲池,如磁盘和网卡,通过缓冲IO的方式读取时,如BufferedInputStream里就有个buf块,CPU可把外设里的缓冲池available的字节块整块读入该buf内存,现在的处理器和外设硬件都是支持按块读取指令的,在大文件读取时,直接打开DMA模式。你完全可以做个测试,如果CPU主频很高,你可以搞个很大的文件来读取,肯定是通过缓冲IO读时,读完整个文件的时间少。

当时学计算机原理,缓冲区的引入就是为了解决CPU与外设的运算速度相差几个数量级的问题。所以在现在我们开发程序时,也是利用这个原理,当两种东西运算速度不是一个数量级时,引入缓冲,以充分发挥运算速度快那东西的资源。总不可能让CPU阻塞地等待一个外设的数据,而不管其他外设数据了;现在的操作系统大部分是多任务操作系统,即使某服务器只运行你的程序,难道你那程序是单线程串行执行的(比如用户输数据时,程序不能干其他活)?至于你说多加几个CPU的问题,一是芯片成本问题,还有就是技术问题,多CPU并行运算芯片并不容易设计。

其实提高性能的根本目的是均衡CPU与外设之间的速度差异,缓存的作用就是这个。可能说的不是很明白。

缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。
  正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。最高达到提高性能的目的。

你还是直接看BufferedInputStream源代码好了

1.如果了解C语言,就知道请求内存(malloc或者new)很影响速度。

而一次请求系统分配1字节的内存和1000字节的内存,用的时间是几乎一样的。

2.大块复制内存操作(memcpy)的时间复杂度和拷贝一个字节在同一个数量级。

3.cpu处理数据是按字节操作的,cpu读cache的数据比读内存的数据快得多;

但是cache读内存可以用类似于memcpy的方法,一次copy连续的一大块;

所以当你处理的数据在内存中处于同一块的时候,速度就很快。

4.内存之于硬盘 类似于 cache之于内存。

综上,避免琐碎的分配内存,对提高速度有很大帮助,所以内存够用时,缓冲区一般越大越快(当然大到一定程度,和cache差不多时,就几乎没效果了)。

ps:总觉得缓冲区这个名字有点对不上本来的意思,buffer不过就是存储数据的一块内存嘛。

再ps:你跑程序的系统肯定不是单线程的,系统还有其他进程/线程在请求和释放内存和使用cpu,如果你其他线程都在睡觉,那么使用buffer与否应该体现不出多大的性能差距。