Java 的 [输入|输出]Streams每个字节一个方法调用:性能问题?
[Input|Output]Streams 自 JDK1.0 起就存在,而其对应的字符 Readers|Writers 自 JDK1.1 起就存在。
大多数概念看起来都很相似,但有一个例外:流的基类声明一个抽象方法,一次处理一个单个字节,而基本读取器/写入器< /strong> 类声明一个处理整个 char 数组的抽象方法。
因此,鉴于我正确理解它,每个重写的 stream 类仅限于处理单个字节(从而对 每个 字节执行至少一个方法调用!),而重写 <读取器/写入器只需要每个数组(-buffer)调用一个方法。
这不是一个巨大的性能问题吗?
流可以作为 InputStream
或 OutputStream
的子类实现,但仍然基于 byte
数组吗?
[Input|Output]Streams exist since JDK1.0, while their character-counterparts Readers|Writers exist since JDK1.1.
Most concepts seem similar, with one exception: the base classes of streams declare an abstract method which processes one single byte at a time, while base readers/writers classes declare an abstract method which processes whole char
-arrays.
Thus, given that I understand it correctly, every overridden stream class is limited to process single bytes (thereby performing at least one method call for each byte!), while overridden readers/writers only need a method call per array(-buffer).
Isn't that a huge performance problem?
Can a stream be implemented as subclass of either InputStream
or OutputStream
, but nevertheless be based on byte
-arrays?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
实际上,InputStream的子类必须重写一次读取单个字节的方法,但也可以重写其他读取字节数组的方法。我认为大多数输入/输出流实际上都是这种情况。
因此,在我看来,这并不是什么性能问题,是的,您可以扩展输入/输出流并基于字节数组。
Actually, subclasses of InputStream have to override the method that reads a single byte at a time, but also can override others methods that read while byte-arrays. I think that's actually the case for most of the Input/Output streams.
So this isn't much of a performance problem, in my opinion, and yes, you can extend Input/Output stream and be based on byte-arrays.
单字节读取几乎总是一个巨大的性能问题。但是如果你阅读InputStream的API文档,你会发现你必须重写read(),但也应该重写read(byte[],int,int)。大多数使用任何类型的 InputStream 的代码无论如何都会调用数组样式的方法,但该函数的默认实现只是通过为每个字节调用 read() 来实现,因此会对性能产生负面影响。
对于 OutputStream 也是如此。
Single byte reading is almost always a huge performance problem. But if you read the API docs of InputStream, you see that you HAVE TO override read(), but SHOULD also override read(byte[],int,int). Most code that uses any kind of InputStream calls the array style method anyway, but the default implementation of that function is just implemented by calling read() for every byte, so the negative performance impact.
For OutputStream the same holds.
正如丹尼尔所说,您必须重写
read()
,因为客户端可能直接使用它,但您也应该重写read(byte[],int,int)
。但是,我怀疑您是否应该关心性能,因为 jvm 可以并且将会为您内联该方法。最重要的是,这对我来说似乎不是问题。
此外,大多数读者在幕后使用一些底层输入流,因此在任何情况下,这些基于字符数组的方法最终都会调用 read(byte[],int,int) 甚至 read( )直接。
As Daniel said, you must override
read()
, since client might use it directly, but you also should overrideread (byte[],int,int)
.However, I doubt if you should be concerned with performance since the jvm can and will inline that method for you. Most of all, it doesn't seem like an issue to me.
Also, most readers use some underlying input stream behind the scene, so in any case those char-array based methods end up calling
read(byte[],int,int)
or evenread()
directly.请注意,
Readers
/Writers
用于读取由多个一个字节组成的字符,例如 unicode 字符。另一方面,当您处理非字符串(二进制)数据时,流更适合。除此之外,
InputStream
和OutputStream
还具有读取/写入整个字节数组的方法。Note that
Readers
/Writers
are for reading characters which can be made of more than one byte such as unicode characters. Streams on the other hand are more suitable when you're dealing with non-string (binary) data.Apart from that,
InputStream
andOutputStream
also have methods to read/write an entire array of bytes.在性能方面,如果您使用 BufferedInputStream 包装它,JVM 应该能够将单字节读取方法调用的开销优化为零,即它与您自己进行缓冲一样快。
performance wise, if you wrap it with BufferedInputStream, JVM should be able to optimize the overhead of single byte read method calls to nothing, i.e. it's as fast as if you do the buffering yourself.