2010-11-05 33 views
6

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

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

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

在此先感谢您的任何答案! :d

回答

6

一个DataInputStream不进行缓冲,所以每一个DataInputStream物体上的读操作是要导致一个或多个上底层套接字流中读取,这可能导致多个系统调用(或等同物) 。

系统调用通常比常规方法调用贵2至3个数量级。缓冲流通过减少系统调用的数量(理想情况下为1)来工作,但需要增加一层额外的常规方法调用。通常使用缓冲流将1个系统调用和N个额外方法调用替换为N个系统调用。如果N大于1,那么你赢了。

由此可见,只有情况下,把流套接字之间的BufferedInputStream和DataInputStream类是双赢是:

  • 当应用程序只会让一个人read...()呼叫,并可以由满足单系统调用,
  • 当应用程序只有很大的read(byte[] ...)调用,或
  • 当应用程序不读取任何东西。

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

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

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

2

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

你说收到的数据是通常是小:你预计多长时间一次?如果您在未缓冲的流上收到偶尔的大消息,那将是一个重大瓶颈。

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

+0

这没有意义。缓冲区在套接字的生命周期中被分配一次。可以有任意数量的读取。读取越缓慢,读取越缓慢。 – EJP 2010-11-05 23:16:27

+0

如果客户端正在连接,发送一条小消息,然后断开(如Ajax-y可能),则缓冲可能效率低下。阅读数量必须非常小,但20-25的范围可能足够低。我不知道:这就是为什么我建议分析。 – 2010-11-05 23:20:10

+0

现在我想到了,AJAX不会给你20-25字节的消息...... XML太冗长了。不过,我*认为客户不会保持联系。如果这个假设是错误的,那么总是使用缓冲区。 – 2010-11-05 23:22:20

相关问题