2012-07-07 21 views
9

Để có được việc chuyển giao nhanh nhất tốc độ trên TCP trong Java, mà là tốt hơn:Ổ cắm: BufferedOutputStream hoặc chỉ OutputStream?

Lựa chọn A:

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

Lựa chọn B:

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

Tôi đã đọc hiệu suất mà sẽ đưa một hit khi viết trên 8 KiB để OutputStream, nó đã được khuyến cáo rằng nó muốn được viết vào nó trong các khối nhỏ không phải pver 8 KiB tại một thời điểm. 8 KiB là kích thước bộ đệm mặc định của BufferedOutputStream.

Tuy nhiên tôi cũng đọc rằng khi chuyển dữ liệu qua mạng, tốt nhất là loại bỏ các byte càng nhanh càng tốt. Có nghĩa là sử dụng một bộ đệm và viết trong các khối nhỏ sẽ làm tăng thêm chi phí không cần thiết.

Vì vậy, tùy chọn A hoặc tùy chọn B? Mà hoạt động tốt nhất?

Ngay bây giờ tôi đoán tùy chọn A cho tốc độ truyền cao nhất trong khi tiêu thụ nhiều CPU hơn tùy chọn B. Tùy chọn B có thể tốt hơn vì không chậm hơn nhiều nhưng tiết kiệm rất nhiều CPU.

-

Bonus câu hỏi: có phải là một ý tưởng tốt để chạm vào kích thước cửa sổ TCP? Ví dụ bằng cách thiết lập nó đến 64 KiB:

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

Tôi đã cố gắng thiết lập nó đến 128 KiB trên một máy tính thử nghiệm kể từ khi tôi đọc rằng nó có thể tăng tốc độ nhưng khi máy chủ nhận được một vài kết nối CPU là 100% thay vì ~ 2% như khi tôi để nó một mình. Tôi đoán 128 KiB là quá cao, trừ khi bạn đã có một máy chủ tốt có thể xử lý mà vội vàng trong giao thông, nhưng là nó thông minh để thiết lập nó đến một cái gì đó giống như 32 KiB? Tôi nghĩ rằng mặc định là 8 KiB ở đó cho tôi.

("ổ cắm" là "java.net.Socket")

Trả lời

6

tôi không biết nơi bạn đọc tất cả những gì vô nghĩa nhưng nó là hoàn toàn sau ra trước. Bạn càng viết vào thời điểm kết nối TCP càng tốt, và càng có nhiều bạn đọc từ nó tại một thời điểm ditto. Tôi sẽ luôn sử dụng luồng đệm, trình đọc hoặc trình ghi giữa ứng dụng và luồng của luồng. Có một số trường hợp như SSL, nơi trực tiếp viết một byte tại một thời điểm có thể gây ra một vụ nổ dữ liệu 40x.

Bạn nên chạm vào kích thước cửa sổ TCP? Ví dụ: bằng cách đặt nó thành 64 KiB

Bạn không thể 'chạm vào kích thước cửa sổ TCP'. Bạn có thể tăng giá trị tối đa của nó thông qua các API mà bạn đề cập, và đó thực sự là một ý tưởng hay.

+0

Sử dụng lõi OutputStream và InputStream không bắt buộc bạn phải viết từng byte một. Điều gì về việc viết mảng byte bằng cách sử dụng các lớp này so với đệm? – Mishax

0

Bạn muốn nói gì về tốc độ? độ trễ thấp hoặc thông lượng cao?

Để có độ trễ thấp, hãy xả luồng ngay sau khi bạn hoàn thành việc viết.

Để có thông lượng cao, hãy sử dụng luồng đệm và để cho VM/OS xử lý việc xả của nó.