【问题标题】:Java's [Input|Output]Streams' one-method-call-for-each-byte: a performance problem?Java 的 [Input|Output]Streams' one-method-call-for-each-byte:性能问题?
【发布时间】:2010-09-04 10:11:13
【问题描述】:

[Input|Output]Streams 从 JDK1.0 开始存在,而它们的字符对应的 Readers|Writers 从 JDK1.1 开始存在。

大多数概念看起来都相似,除了一个例外:的基类声明了一个抽象方法,该方法一次处理一个单个字节,而基本读取器/writers 类声明了一个处理整个char-arrays 的抽象方法。

因此,鉴于我理解正确,每个被覆盖的 stream 类都仅限于处理单个字节(从而对 每个 字节执行至少一个方法调用!),而被覆盖的 readers/writers 只需要每个数组(-buffer)的方法调用。

这不是一个巨大的性能问题吗?

流可以实现为InputStreamOutputStream 的子类,但仍基于byte-arrays?

【问题讨论】:

    标签: java io stream writer


    【解决方案1】:

    实际上,InputStream 的子类必须重写一次读取单个字节的方法,但也可以重写其他读取字节数组的方法。我认为大多数输入/输出流实际上都是这种情况。

    所以在我看来,这并不是什么性能问题,是的,您可以扩展输入/输出流并基于字节数组。

    【讨论】:

      【解决方案2】:

      单字节读取几乎总是一个巨大的性能问题。但是如果你阅读 InputStream 的 API 文档,你会发现你必须重写 read(),但也应该重写 read(byte[],int,int)。大多数使用任何类型 InputStream 的代码都会调用数组样式方法,但该函数的默认实现只是通过为每个字节调用 read() 来实现,因此会对性能产生负面影响。

      对于 OutputStream 也是如此。

      【讨论】:

        【解决方案3】:

        正如丹尼尔所说,您必须覆盖read(),因为客户端可能会直接使用它,但您也应该覆盖read (byte[],int,int)

        但是,我怀疑您是否应该关注性能,因为 jvm 可以并且将为您内联该方法。最重要的是,这对我来说似乎不是问题。

        此外,大多数读者在后台使用一些底层输入流,因此无论如何这些基于字符数组的方法最终都会直接调用read(byte[],int,int) 甚至read()

        【讨论】:

          【解决方案4】:

          请注意,Readers/Writers 用于读取由多于 个字节组成的字符,例如 unicode 字符。另一方面,流更适合处理非字符串(二进制)数据。

          除此之外,InputStreamOutputStream 还具有读取/写入整个字节数组的方法。

          【讨论】:

          • 我知道,我说的是抽象方法。但是现在,您和其他回答者明确表示,其他方法也适合被覆盖。
          【解决方案5】:

          在性能方面,如果你用 BufferedInputStream 包装它,JVM 应该能够将单字节读取方法调用的开销优化到零,即它就像你自己做缓冲一样快。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-12
            • 1970-01-01
            • 1970-01-01
            • 2022-12-02
            相关资源
            最近更新 更多