[英]Speed up my Java tcp transfer!
我需要加快千兆以太網連接之間的傳輸速度。 現在,我正在做幾乎完全像這樣的事情,但是當我在下面運行此代碼時,我只看到其中的40%。
在測試之前,我還在所有(Mac Pro)計算機上運行了此腳本
#!/bin/bash
sudo sysctl -w net.inet.tcp.win_scale_factor=8
sudo sysctl -w kern.ipc.maxsockbuf=16777216
sudo sysctl -w net.inet.tcp.sendspace=8388608
sudo sysctl -w net.inet.tcp.recvspace=8388608
實際代碼如下:
import java.io.*;
import java.nio.*;
import java.net.*;
public class BandwidthTester {
private static final int OUT_BUF = (1 << 17),
IN_BUF = (1 << 17), SEND_BUF = (1 << 22), RECV_BUF = (1 << 22);
public static void main(String[] args) {
try {
// server
if (args.length == 0) {
ServerSocket sock = new ServerSocket();
sock.bind(new InetSocketAddress(41887));
// wait for connection
Socket s = sock.accept();
s.setSendBufferSize(SEND_BUF);
System.out.println("Buffers: " + s.getSendBufferSize() + " and " + s.getReceiveBufferSize());
sock.close();
BufferedOutputStream bOut = new BufferedOutputStream(s.getOutputStream(), OUT_BUF);
// send lots of data
sendLotsOfData(bOut);
} else if (args.length == 2) {
String host = args[0];
int port = Integer.parseInt(args[1]);
System.out.println("Connecting to " + args[0] + ":" + args[1]);
Socket sock = new Socket();
sock.setReceiveBufferSize(RECV_BUF);
sock.connect(new InetSocketAddress(host, port));
System.out.println("Buffers: " + sock.getSendBufferSize() + " and " + sock.getReceiveBufferSize());
BufferedInputStream bIn = new BufferedInputStream(sock.getInputStream(), IN_BUF);
getLotsOfData(bIn);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void getLotsOfData(InputStream in) {
System.out.println("Getting data...");
try {
long start = System.currentTimeMillis();
ByteBuffer intConv = ByteBuffer.allocate(4);
in.read(intConv.array());
int len = intConv.getInt(0);
for (int i=0; i < len; i++) {
in.read(intConv.array());
int val = intConv.getInt(0);
}
long end = System.currentTimeMillis();
double elapsed = ((double)(end - start)) / (1000.0);
System.out.println("Read in " + elapsed + " seconds: " + ( (4.0*8.0*len/elapsed) + " bits per second"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sendLotsOfData(OutputStream out) {
System.out.println("Sending data...");
try {
long start = System.currentTimeMillis();
int len = (1 << 29);
ByteBuffer intConv = ByteBuffer.allocate(4);
intConv.putInt(0, len);
out.write(intConv.array());
for (int i=0; i < len; i++) {
intConv.putInt(0, i);
out.write(intConv.array());
}
out.flush();
long end = System.currentTimeMillis();
double elapsed = ((double)(end - start)) / (1000.0);
System.out.println("Sent in " + elapsed + " seconds: " + ( (4.0*8.0*len/elapsed) + " bits per second"));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
有什么建議么? 發送所有這些數據大約需要42秒鍾,但即使在此處提高10%,也會對我的程序產生巨大影響。
您可以嘗試的一件事是為ByteBuffer使用更大的緩沖區。 從4字節變為16,我從12秒的傳輸時間變為9秒的傳輸時間。 (使用2 ^ 26而不是2 ^ 29進行測試)
也就是說,它正在本地運行; 因此,應該不會遇到實際的網絡問題。
用於發送的一些臟修改代碼:
ByteBuffer intConv = ByteBuffer.allocate(16);
intConv.putInt(0, len);
out.write(intConv.array(),0,4);
for (int i=0; i < len; i+=4) {
for(int j=0; j<4; j++)
intConv.putInt(4*j, i);
out.write(intConv.array());
}
和接收:
ByteBuffer intConv = ByteBuffer.allocate(16);
in.read(intConv.array(),0,4);
int len = intConv.getInt(0);
for (int i=0; i < len; i+=4) {
in.read(intConv.array());
for(int j=0; j<4; j++)
{
int val=intConv.getInt(j*4);
}
}
顯然,接收端將需要進行一些修改以處理奇怪的情況,例如“如果流中僅剩余3個int /從流中讀取數據,將會怎樣?”,但我認為這足以查看它是否可以提高性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.