【问题标题】:Java I/O classes and performanceJava I/O 类和性能
【发布时间】:2011-05-25 06:42:07
【问题描述】:

在 Java 第 4 版中阅读思维。我对 I/O 操作性能有一些疑问: 我读过最好在 BufferedInputStream 中“包装”InputStream 对象,但在我看来,我看不出有什么区别。即文件操作不是已经缓冲了吗?文件缓冲写有什么好处?

【问题讨论】:

  • 嗯,这就是我最初的想法。但是如果 InputStream 读取一个字节,包装类 BufferedInputStream 应该从包装的 InputStream 调用 InputStream.read 次,导致 访问磁盘,不是吗?
  • 我认为您误解了InputStream API。它有三个名为read 的方法。其中两种方法允许批量操作(在byte[] 数组上)。在内部,BufferedInputStream 保留一个 byte[] 数组作为其缓冲区。它将使用其他InputStream 的批量方法填充其缓冲区,从而最大限度地减少调用次数。因此,如果您正在读取一个 500 字节的文件,而 BufferedInputStream 正在缓冲 100 字节,则另一个 InputStream 的批量 read 方法将被调用 5 次。
  • @Adam Paynter:好的。这才是重点。通过 5 次调用 InputStream.read(byte[100]) 或使用 BufferedInputStream(InputStream, 100) 5 次调用 InputStream.read(byte[100]) 读取 500 字节文件是否具有相同的行为?
  • 如果BufferedInputStream 实际上是缓冲 100 个字节那么你是对的,没有区别。如果您想要一次消耗小于 100 个的块中的字节,它可以提供优势。理论上,您可以一次使用一个字节的 500 字节文件,但 BufferedInputStreamStream 将确保只进行 5 次系统调用。
  • 好吧……正如作者不断重复的那样,包装到 BufferedInputStream 始终是正确的选择,我认为它会做一些特殊的优化。谢谢回复,再见:)

标签: java file


【解决方案1】:

系统的 IO 缓冲与 Buffered*putStream 处于不同级别。

FileOutputStream.write(...) 上的每次调用都会引发本地方法调用(这通常比 java 内部调用更昂贵),然后上下文切换到操作系统内核以进行实际写入。即使内核(或文件系统驱动程序或硬盘控制器或硬盘本身)正在做更多的缓冲,也会产生这些成本。

通过将 BufferedOutputStream 包裹起来,我们将减少调用本机 write 方法的频率,从而允许更高的吞吐量。

(对于其他类型的IO同样适用,当然我只是以FileOutputStream为例。)

【讨论】:

    【解决方案2】:

    文件操作不是已经缓冲了吗?

    也许,也许不是 - 取决于操作系统、使用的 HD、访问方式(例如读取大的连续块与随机访问整个地方的小块)等。在最坏的情况下,添加 BufferedInputStream 可能会获胜不会明显损害性能。在最好的情况下,它可以大大提高它(用一次大读/写替换许多小文件访问)。

    【讨论】:

    • +1:大多数操作系统会为您处理大部分缓冲。这可能会导致系统调用产生最大的命中。
    • 可能是真的,但程序员对用例的了解比操作系统要多得多,这也是真的。例如,程序将连续读取 2MB。您自己的 2MB 缓冲区比操作系统所做的任何事情都要大得多,在这个级别上,您还可以节省物理 I/O 的时间。
    【解决方案3】:

    InputStream 只会请求您请求的数据,因此如果您一次请求 1000 个字符一个字符,结果将是 1000 次单独的磁盘访问,这将变得非常慢。

    然而,BufferedInputStream 会以更大的块从InputStream 请求数据,从而减少对单独磁盘访问的需求。

    输出也是如此,而不是单独写入每个字符,BufferedOutputStream 的物理磁盘写入更少。

    【讨论】:

    • 仅供参考:在大多数操作系统上,单独请求 n 个字符不会导致 n 个磁盘访问。
    • 啊,好吧,只是想让它成为 n chars = n 访问以展示缓冲版本的有用性。
    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2012-08-06
    • 2013-02-05
    • 2010-09-25
    • 1970-01-01
    • 2020-01-24
    • 2020-08-11
    相关资源
    最近更新 更多