【发布时间】:2017-12-20 17:29:48
【问题描述】:
我有两个相同的 Java 程序集 [Server.java 和 Client.java] 和 [ServerTest.java 和 ClientTest.java] 的变体。它们都做同样的事情,客户端连接到服务器并将成对的整数发送到服务器以进行相乘,并将结果返回给客户端,然后在客户端打印。每次执行 100 次。
但是,在测试版本中,我为整数对的每次传递及其乘法(执行 100 次乘法)创建并关闭一个新套接字。在普通版本中,我打开一个持久套接字并执行与客户端的所有交互,然后关闭。
直观地说,我认为创建一个持久套接字的方法比每次创建、接受和关闭一个套接字要快一些——实际上,创建、接受和关闭一个新套接字的方法明显更快。平均而言,持久套接字方法大约需要 8 秒,而每次创建一个新套接字的方法大约需要 0.4 秒。
我检查了两者的系统调用活动,发现两者之间没有什么不同。然后我在另一台计算机(macOS Sierra)上测试了相同的程序,两者之间的差异可以忽略不计。因此,问题似乎不在于应用程序代码,而在于它与操作系统的交互方式(我运行的是 Ubuntu LTS 16.04)。
有谁知道为什么这里的性能会有如此大的差异,或者如何进一步调查这个问题?在执行程序时,我还检查了系统范围的指标(内存使用率和 CPU 使用率),似乎有足够的内存并且 CPU 有足够的空闲时间。
请参阅下面的代码 sn-p,了解两种方法的不同之处:
每次创建新套接字的方法:
// this is called one hundred times
public void listen() {
try {
while (true) {
// Listens for a connection to be made to this socket.
Socket socket = my_serverSocket.accept();
DataInputStream in = new DataInputStream(socket
.getInputStream());
// Read in the numbers
int numberOne = in.readInt();
int numberTwo = in.readInt();
int result = numberOne * numberTwo;
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(result);
// tidy up
socket.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
持久套接字方法:
public void listen() {
try {
while (true) {
// Listens for a connection to be made to this socket.
Socket socket = my_serverSocket.accept();
for (int i = 0; i < 100; i++) {
DataInputStream in = new DataInputStream(socket
.getInputStream());
// Read in the numbers
int numberOne = in.readInt();
int numberTwo = in.readInt();
int result = numberOne * numberTwo;
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(result);
}
// tidy up
socket.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
【问题讨论】:
标签: java performance sockets