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”)
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