2011-04-28 21 views

回答

2

是不是比較好發送四個Object[5](每個沖洗一個)比Object[20],例如?

這是不是更好。事實上,從性能角度來看,這可能更糟。每次刷新都會強制OS級TCP/IP堆棧「立即」發送數據。如果您最後只進行一次刷新,則應節省系統調用和網絡流量。

如果你還沒有這樣做了,插入SocketOutputStreamObjectOutputStream一個BufferedOutputStream之間將會使性能大大較大的差異。這允許序列化的數據在寫入套接字流之前在內存中累積。這可能會節省很多系統調用,並且可以通過數量級提高 ...的性能,具體取決於要發送的實際對象。

(4個Object[5]對象的表示是多於一個的Object[20]對象大,導致在所述第一情況下的性能損失。然而,這是邊際至多,以及微小與沖洗和緩衝問題相比較。)

此流如何在內部工作?

這是過於籠統問題理智回答。我建議您閱讀關於this page上的文檔的序列化。

1

不,它不應該的問題,除非你有理由相信網上的鏈接很可能往下走,而部分數據是非常有用的。否則,這聽起來像是一種無緣無故地讓代碼更復雜的方法。

1

如果你看一下the one and only public constructor of ObjectOutputStream,您注意它需要它的實例化一個基本OutputStream

何時以及如何刷新ObjectStream完全取決於您正在使用的流的類型。 (考慮到所有這些,請記住並非所有OutputStream的擴展都保證尊重您的刷新請求 - it is entirely implementation independent,因爲它是在javadocs的'合同'中闡明的。)

但肯定我們可以推斷它,甚至拉起代碼,看看實際做了什麼。

IFF底層OutputStream必須利用設備的操作系統服務(例如磁盤或the network interface in case of Sockets),那麼flush()的行爲完全取決於操作系統。例如,您可以獲取套接字的輸出流,然後實例化ObjectOutputStream以將序列化對象寫入網絡。主機OS的TCP/IP實施負責。

什麼更有效?那麼,如果你的對象流正在包裝一個ByteArrayOutputStream,你可能是看着一系列reallocs和System.arrayCopy()調用。我可能會說,因爲字節數組的實現使每個(內部)resize()op的大小加倍,所以每次寫入n個(小)對象和刷新都會導致n個reallocs,這是不太可能的。 (其中n被認爲是相當小的數字)。

但是,如果您要封裝網絡流,則必須記住網絡寫入非常昂貴。如果您的協議允許它更合理地分塊寫入(填充發送緩衝區)並只刷新一次。