使用缓冲流来发送对象?

时间:2014-10-11 23:03:29

标签: java sockets iostream bufferedreader

我目前正在使用OutputStream而不是BufferedOutputStream的客户端 - 服务器应用程序中使用Java套接字(对于输入流也是如此)。

客户端和服务器交换序列化对象(writeObject()方法)。

在这种情况下使用BufferedOutputStream和BufferedInputStream是否有意义(更快)?

当我必须刷新或者我不应该写一个flush()语句?

2 个答案:

答案 0 :(得分:7)

  

在这种情况下使用BufferedOutputStream和BufferedInputStream是否有意义(更快)?

实际上,它可能有意义 1

对象流实现在内部用一个名为BlockDataOutputStream的私有类进行缓冲,它包含了它所提供的流。如果你自己包装流,你将有两个级别的缓冲...这可能会使性能更差 2

  

当我必须刷新或者我不应该写一个flush()语句?

是的,可能需要冲洗。但 时没有普遍的答案。

  • 一方面,如果您经常刷新,则会产生额外的网络流量。

  • 另一方面,如果您在需要时不刷新,服务器可能会停止等待客户端已写入但未刷新的对象。

您需要找到这两种综合症之间的妥协......这取决于您的应用程序的客户端/服务器交互模式;例如消息模式是同步的(例如消息/响应)还是异步的(例如消息流)。


1 - 为了确定这一点,您需要进行一些取证测试,1)测量系统性能,2)确定进行的系统调用以及何时发送网络数据包。对于一般答案,您需要对许多用例重复此操作。我还建议您自己查看Java库代码以确认我的(简短)阅读。

2 - 可能只是有点更糟糕,但设计良好的基准测试会带来很小的性能差异。


<强>更新

在写完上述内容之后,我发现了这个Q&amp; A - Performance issue using Javas Object streams with Sockets - 这似乎表明使用BufferedInputStream / BufferedOutputStream有帮助。但是,由于缓冲,我不确定所报告的性能改进是1)真实的(即不是热身伪影)和2)。这可能只是因为添加了flush()电话。 (为什么:因为刷新可能导致网络堆栈更快地推送数据。)

答案 1 :(得分:0)

我认为这些链接可能会对您有所帮助:

What is the purpose of flush() in Java streams?

  

flush方法刷新输出流并强制写出任何缓冲的输出字节。 flush的一般合同是调用它表示,如果先前写入的任何字节已被输出流的实现缓冲,则应立即将这些字节写入其预期目的地。

How java.io.Buffer* stream differs from normal streams?

  

在内部使用缓冲区数组,而不是从底层输入流中单独读取字节,而是读取足够的字节来填充缓冲区。这通常会导致更快的性能,因为底层输入流需要更少的读取。

http://www.oracle.com/technetwork/articles/javase/perftuning-137844.html

  

作为开始讨论的一种方式,这里有一些关于如何加速I / O的基本规则:1。避免访问磁盘。 2.避免访问底层操作系统。 3.避免方法调用。 4.避免单独处理字节和字符。

因此,使用Buffered-Streams通常会加快IO处理速度,因为后台执行的read()更少。