我测试了在一台计算机上通过套接字将数据从一个程序传输到另一个程序的性能,速度 120MBytes / s ,这是正常的吗?
我的服务器和客户端程序都非常简单。
我的电脑是AMD Athlon X2 4000 +,4G DDR2 667内存,带有windows xp sp3。
我的朋友说它很慢,应该更快。但我不知道如何改进它们,或者是否有其他库可以尝试获得更好的速度?
更新
服务器和客户端程序都在我自己的计算机上,一台计算机。 网卡会限制速度吗?
Server.java
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(6666);
Socket socket = server.accept();
OutputStream output = socket.getOutputStream();
byte[] bytes = new byte[10 * 1024]; // 10K
for (int i = 0; i < bytes.length; i++) { bytes[i] = 12; } // fill the bytes
// send them again and again
while (true) {
output.write(bytes);
}
}
}
Client.java
public class SimpleClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 6666);
InputStream input = socket.getInputStream();
long total = 0;
long start = System.currentTimeMillis();
byte[] bytes = new byte[10240]; // 10K
// read the data again and again
while (true) {
int read = input.read(bytes);
total += read;
long cost = System.currentTimeMillis() - start;
if (cost > 0 && System.currentTimeMillis() % 1000 == 0) {
System.out.println("Read " + total + " bytes, speed: " + (total / (1024.0*1024)) / (cost / 1000.0) + " MB/s");
}
}
}
}
答案 0 :(得分:12)
你能告诉我这个程序的输出吗?
public class SimpleServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(6666);
Socket socket = server.accept();
OutputStream output = socket.getOutputStream();
byte[] bytes = new byte[32*1024]; // 32K
while (true) {
output.write(bytes);
}
}
}
public class SimpleClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 6666);
InputStream input = socket.getInputStream();
long total = 0;
long start = System.currentTimeMillis();
byte[] bytes = new byte[32*1024]; // 32K
for(int i=1;;i++) {
int read = input.read(bytes);
if (read < 0) break;
total += read;
if (i % 500000 == 0) {
long cost = System.currentTimeMillis() - start;
System.out.printf("Read %,d bytes, speed: %,d MB/s%n", total, total/cost/1000);
}
}
}
}
我机器上的打印
Read 25,586,204,672 bytes, speed: 5,245 MB/s
Read 53,219,426,304 bytes, speed: 5,317 MB/s
Read 85,018,968,064 bytes, speed: 5,416 MB/s
Read 117,786,968,064 bytes, speed: 5,476 MB/s
尝试多次发送32K块(至少2秒),你应该得到400 MB / s或更多。例如至少10,000次。
在速度非常快的计算机上,您可以在单个客户端上获得1 GB / s的速度。对于多个客户端,您可能会获得8 GB / s。
这是一个例子
Making file transfer more efficient Java
如果你有100 Mb卡,你可以期望大约11 MB / s(每秒字节数)。
类似地,对于1 Gb以太网,您需要大约110 MB / s
对于10 Gig-E以太网,您可能会达到1 GB / s,但是您可能只能获得一半的这个unles syour系统。
答案 1 :(得分:10)
您只传输10k字节来执行测试。您正在做的很多事情都会产生开销,而这样一小部分数据可能会受到这种开销的影响。 (例如,创建套接字,分配内存等)。您应该创建并传输更大的数据集(几十MB +),以更真实地了解正在发生的事情。这样做会使开销成为数据传输过程中较小的,不太重要的部分。
您还应多次执行此测试(&gt; 10)并取平均值,因为您的计算机将在不同的随机时间点受到来自服务,网络传输等的负载,这些负载将影响您的转移率。通过10次迭代,您还可以删除异常缓慢的任何运行时间,例如&gt; 2个标准偏差。
答案 2 :(得分:5)
网卡是否会限制速度?
您正在使用127.0.0.1 - 本地/环回地址。来自/到该地址的流量不会通过网卡。
这意味着这不是衡量实际网络吞吐量的有效方法。但是,它可以合理地衡量Java在您的计算机上通过本地网络堆栈移动数据的能力。
有趣的是将您获得的结果与用C或C ++编写的等效客户端/服务器对进行比较。
答案 3 :(得分:1)
测试同一主机中两个对等体之间的带宽根本不会运行NIC或网络,而是全部回送。因此,您的数据基本上没有意义。在两台计算机之间尝试。
答案 4 :(得分:0)
WinXP不支持自动窗口缩放,并且套接字的发送/接收缓冲区大小可能太低而无法进行吞吐量测试。
更多FileInputStream(套接字实际上使用FileInputStream)在Windows上的char []缓冲区比本机代码中的Linux小。读/写是通过堆栈上的辅助缓冲区完成的,你输入的大块是通过它进行的。
使用大型直接缓冲区(与套接字缓冲区一样大)是吞吐量的最佳选择。
答案 5 :(得分:0)
嗯,这很有意思,但是这个nio实现与上面提供的SimpleServer / SimpleClient相同(有时实际上超过了它)(虽然这只是在单线程模式下运行,而且反正是一对一的! !)
SimpleServer / SimpleClient和此目录中提供的nio IntegTestLocalhostThroughput.java ......
我只是觉得非常有趣的是,nio基本上同样快,但比旧的io更好。