根据官方文档,Java实现Buffered Streams的原因之一是
到目前为止,我们看到的大多数示例都使用无缓冲 I/O。这意味着每个读取或写入请求都由底层操作系统直接处理。这可能会大大降低程序的效率,因为每个此类请求通常都会触发磁盘访问、网络活动或一些其他相对昂贵的操作。
来源:https://docs.oracle.com/javase/tutorial/essential/io/buffers.html
与多个小型读/写请求相比,Linux 上的单个大型读/写请求真的很昂贵吗?与后者相比,前者的效率如何?
答案1
我认为那里的文本指的是应用程序内的缓冲。这通常是由 C 库完成的。例如,如果您调用getchar()
,C 库不会向操作系统请求单个字节,而是读取整个块(通常是几千字节),因此下一个getchar()
不需要进行系统调用。从进程内的缓冲区返回数据比必须涉及从用户模式切换到内核模式的系统调用要快得多。
与多个小型读/写请求相比,Linux 上的单个大型读/写请求真的很昂贵吗?
大请求可能更便宜,因为它节省了多个小请求的开销。但你这个想法是从哪里来的呢?我看不到链接文档提及大请求或小请求?
答案2
由于磁盘块通常由操作系统缓存,因此大多数短时间读取和写入不需要直接访问设备。此外,操作系统通常会注意到您何时读取两个连续的块,并对下一个块发出抢占式预读,因此在您需要时它已经被缓存了。
然而,还有一个重要的额外性能问题正在发挥作用。当您的进程进行系统调用时,它会将 CPU 交给任何其他准备运行的进程。当您的系统调用得到满足后,您的进程就会进入调度程序队列并等待轮到运行。如果混合中存在 CPU 密集型进程,它们每次调度时都会使用最大时间片,而您的进程在每次访问时都会挂在该时间片后面。