2012-07-07 16 views
9

Aby uzyskać najszybszą szybkość transferu przez TCP w Java, która jest lepsza:Gniazda: BufferedOutputStream lub po prostu OutputStream?

Wariant A:

InputStream in = socket.getInputStream(); 
OutputStream out = socket.getOutputStream(); 

Wariant B:

BufferedInputStream in = new BufferedInputStream(socket.getInputStream()); 
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 

Czytałem, że wydajność trwa hit przy zapisywaniu ponad 8 KiB do OutputStream, zalecane było, aby był zapisywany na nim w małych kawałkach, nie przesyłając 8 KiB na raz. 8 KiB jest domyślnym rozmiarem bufora BufferedOutputStream.

Jednak przeczytałem również, że przy przesyłaniu danych przez sieć dobrze jest opróżnić bajty tak szybko, jak to możliwe. Oznacza to, że użycie bufora i pisanie w małych fragmentach dodaje niepotrzebny narzut.

A więc opcja A lub opcja B? Który działa najlepiej?

Właśnie zgaduję, że opcja A zapewnia najwyższe prędkości transferu, zużywając o wiele więcej procesora niż opcja B. Opcja B może być lepsza, ponieważ nie jest wolniejsza, ale oszczędza dużo procesora.

-

Bonus pytanie: Czy to dobry pomysł, aby dotknąć rozmiaru okna TCP? Na przykład poprzez ustawienie go na 64 KiB:

socket.setReceiveBufferSize(65536); 
socket.setSendBufferSize(65536); 

Próbowałem ustawienie go do 128 KiB na maszynie testowej ponieważ czytałem, że może to zwiększyć prędkość ale gdy serwer ma kilka połączeń CPU były na 100% zamiast ~ 2% jak wtedy, gdy zostawiłem to w spokoju. Domyślam się, że 128 KiB jest zdecydowanie za wysokie, chyba że masz dobry serwer, który poradzi sobie z tym ruchem w ruchu, ale czy mądrze jest ustawić go na 32 klocki? Myślę, że domyślny był dla mnie 8 KiB.

(„gniazdo” jest „java.net.Socket”)

Odpowiedz

6

nie wiem, gdzie można przeczytać cały ten nonsens, ale to jest całkowicie z powrotem do przodu. Im więcej piszesz do połączenia TCP, tym lepiej i im więcej czytasz w tym czasie. Zawsze używałbym zbuforowanego strumienia, czytnika lub programu piszącego między aplikacją a strumieniami gniazd. Jest kilka przypadków takich jak SSL, w których bezpośrednie zapisywanie bajtu w tym samym czasie może spowodować 40-krotny wybuch danych.

Czy to jest dobry pomysł, aby dotknąć rozmiaru okna TCP? Na przykład ustawiając go na 64 KiB

Nie można "dotknąć rozmiaru okna TCP". Możesz zwiększyć jego maksymalną wartość za pomocą interfejsów API, o których wspomniałeś, i to jest naprawdę dobry pomysł.

+0

Korzystanie z rdzenia OutputStream i InputStream nie wymusza na pisaniu bajtów jeden po drugim. A co z pisaniem tablic bajtowych używających tych klas w porównaniu do buforowania? – Mishax

0

Co masz na myśli przez prędkość? małe opóźnienie lub wysoka przepustowość?

Aby uzyskać małe opóźnienie, przepłucz strumień natychmiast po zakończeniu zapisywania.

Aby uzyskać wysoką przepustowość, użyj zbuforowanego strumienia i pozwól, aby system VM/OS obsługiwał proces płukania.

Powiązane problemy