我目前正在使用OutputStream而不是BufferedOutputStream的客户端 - 服务器应用程序中使用Java套接字(对于输入流也是如此)。
客户端和服务器交换序列化对象(writeObject()方法)。
在这种情况下使用BufferedOutputStream和BufferedInputStream是否有意义(更快)?
当我必须刷新或者我不应该写一个flush()语句?
答案 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()更少。