简体   繁体   English

Java - 使用带有套接字的DataInputStream,是否缓冲?

[英]Java - Using DataInputStream with Sockets, buffered or not?

I'm writing a simple client/server application and I found that using DataInputStream to read data was very convenient because it allows you to chose what to read (without having to convert it yourself from bytes), but I'm wondering if it would be best to wrap it in a BufferedInputStream too, or if that would just add unnecessary overhead? 我正在编写一个简单的客户端/服务器应用程序,我发现使用DataInputStream读取数据非常方便,因为它允许您选择要读取的内容(无需自己从字节转换),但我想知道它是否会最好将它包装在BufferedInputStream中,或者如果这只会增加不必要的开销?

The reason I'm asking is because I don't know how expensive it is to read directly from the socket stream (when using a BufferedInputStream it will just read once from the socket stream and then multiply times from the BufferedInputStream using DataInputStream). 我问的原因是因为我不知道直接从套接字流中读取是多么昂贵(当使用BufferedInputStream时,它只会从套接字流中读取一次,然后使用DataInputStream从BufferedInputStream中乘以时间)。

The data received is usually pretty small, around 20-25 Bytes. 收到的数据通常很小,大约20-25字节。

Thanks in advance for any answer! 提前感谢您的回答! :D :d

A DataInputStream is not buffered, so each read operation on a DataInputStream object is going to result in one or more reads on the underlying socket stream, and that could result in multiple system calls (or the equivalent). DataInputStream没有缓冲,因此DataInputStream对象上的每个读取操作都将导致对底层套接字流进行一次或多次读取,这可能导致多个系统调用(或等效的)。

A system call is typically 2 to 3 orders of magnitude more expensive than a regular method call. 系统调用通常比常规方法调用贵2到3个数量级。 Buffered streams work by reducing the number of system calls (ideally to 1), at the cost of adding an extra layer of regular method calls. 缓冲流通过减少系统调用的数量(理想情况下为1)来工作,但代价是添加额外的常规方法调用层。 Typically using a buffered stream replaces N syscalls with 1 syscall and N extra method calls. 通常使用缓冲流用1个系统调用和N个额外方法调用替换N个系统调用。 If N is greater than 1, you win. 如果N大于1,你就赢了。

It follows that the only cases where putting a BufferedInputStream between the socket stream and the DataInputStream is not a win are: 因此,在套接字流和DataInputStream之间放置BufferedInputStream的唯一情况不是 win:

  • when the application only makes one read...() call and that can be satisfied by a single syscall, 当应用程序只进行一次read...()调用并且可以通过单个系统调用来满足时,
  • when the application only does large read(byte[] ...) calls, or 当应用程序只进行大量的read(byte[] ...)调用时,或者
  • when the application doesn't read anything. 当应用程序没有读取任何内容时。

It sounds like these don't apply in your case. 听起来这些不适用于您的情况。

Besides, even if they do apply, the overhead of using a BufferedInputStream when you don't need to is relatively small. 此外,即使它们确实适用,当你不需要时使用BufferedInputStream的开销相对较小。 The overhead of not using a BufferedInputStream when you do need to can be huge. 当你需要时,不使用BufferedInputStream的开销很大。

One final point, the actual amount of data read (ie the size of the messages) is pretty much irrelevant to the buffered versus unbuffered conundrum. 最后一点,实际读取的数据量(即消息的大小)与缓冲与未缓冲的难题几乎无关 What really matters is the way that data is read; 真正重要的是读取数据的方式; ie the sequence of read...() calls that your application will make. 即应用程序将执行的read...()调用序列。

The general wisdom is that individual reads on the underlying stream are very slow so buffering almost always is faster. 一般的智慧是对底层流的单独读取非常慢,因此缓冲几乎总是更快。 However, for such small numbers (20-25 bytes) it might be that the cost of allocating the buffer is similar to the cost of making those individual reads (once you consider memory allocation and garbage collection). 但是,对于如此小的数字(20-25字节),分配缓冲区的成本可能与进行单独读取的成本相似(一旦考虑内存分配和垃圾收集)。 Unfortunately, the only way to find out is to test it and see. 不幸的是,找出答案的唯一方法是测试并查看。

You say that the data received is usually small: how often do you expect larger messages? 您说收到的数据通常很小:您预计更频繁的邮件频率是多少? That will be a significant bottleneck if you receive occasional large messages on an unbuffered stream. 如果您在无缓冲的流上偶尔收到大量消息,那将是一个重大的瓶颈。

I'd suggest that you run some timing tests and see if buffering makes a difference in your case. 我建议你运行一些计时测试,看看缓冲是否会对你的情况产生影响。 Or, don't bother with timing tests and just use a buffer. 或者,不要打扰时间测试,只需使用缓冲区。 If the message size changes in the future then this will reduce maintenance later on. 如果将来邮件大小发生变化,那么这将在以后减少维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM