7

我正在编写一个简单的客户端/服务器应用程序,我发现使用 DataInputStream 读取数据非常方便,因为它允许您选择要读取的内容(无需自己从字节转换),但我想知道它是否会最好也将它包装在 BufferedInputStream 中,或者这只会增加不必要的开销?

我问的原因是因为我不知道直接从套接字流读取是多么昂贵(当使用 BufferedInputStream 时,它只会从套接字流中读取一次,然后使用 DataInputStream 从 BufferedInputStream 乘以时间)。

接收到的数据通常很小,大约 20-25 字节。

提前感谢您的任何回答!:D

4

2 回答 2

7

DataInputStream 没有缓冲,因此对DataInputStream对象的每次读取操作都会导致对底层套接字流的一次或多次读取,这可能导致多次系统调用(或等效调用)。

系统调用通常比常规方法调用贵 2 到 3 个数量级。缓冲流通过减少系统调用的数量(理想情况下为 1)来工作,但代价是增加了一层额外的常规方法调用。通常使用缓冲流将 N 系统调用替换为 1 个系统调用和 N 个额外的方法调用。如果 N 大于 1,则您获胜。

因此,在套接字流和 DataInputStream 之间放置 BufferedInputStream 的唯一情况

  • 当应用程序只进行一次read...()调用并且可以通过单个系统调用来满足时,
  • 当应用程序只进行大型read(byte[] ...)调用时,或者
  • 当应用程序没有读取任何内容时。

听起来这些不适用于您的情况。

此外,即使它们确实适用,在不需要时使用 BufferedInputStream 的开销也相对较小。确实需要时不使用 BufferedInputStream 的开销可能很大。

最后一点,实际读取的数据量(即消息的大小)与缓冲与非缓冲的难题几乎无关。真正重要的是读取数据的方式。即read...()您的应用程序将进行的调用顺序。

于 2010-11-05T22:49:29.993 回答
2

一般的看法是,对底层流的单独读取非常慢,因此缓冲几乎总是更快。但是,对于如此小的数字(20-25 字节),分配缓冲区的成本可能与进行这些单独读取的成本相似(一旦考虑内存分配和垃圾收集)。不幸的是,找出答案的唯一方法是测试并查看。

您说收到的数据通常很小:您期望多久收到一次较大的消息?如果您在无缓冲的流上偶尔收到大消息,那将是一个严重的瓶颈。

我建议你运行一些时间测试,看看缓冲是否对你的情况有影响。或者,不要打扰时间测试,只需使用缓冲区。如果将来消息大小发生变化,那么这将减少以后的维护。

于 2010-11-05T22:51:40.073 回答