我在Java中有以下代码:
public class ServerInfo {
int serverId;
int serverDataRate;
public ServerInfo(int serverId, int serverDataRate) {
this.serverId = serverId;
this.serverDataRate = serverDataRate;
}
public int getServerId() {
return serverId;
}
public double getServerDataRate() {
return serverDataRate;
}
public String toString(){
return serverId + ":" + serverDataRate;
}
}
public class ServerInfoComparator implements Comparator<ServerInfo> {
@Override
public int compare(ServerInfo o1, ServerInfo o2) {
double datarate1=o1.getServerDataRate();
double datarate2=o2.getServerDataRate();
if(datarate1>datarate2)
return -1;
else if(datarate1<datarate2)
return +1;
else
return 0;
}
}
public class Sample {
List<ServerInfo> listOfServers= new ArrayList<ServerInfo>();
public void insertIntoList(){
listOfServers.add( new ServerInfo(0,256));
listOfServers.add( new ServerInfo(1,270));
listOfServers.add( new ServerInfo(2,256));
listOfServers.add( new ServerInfo(3,290));
listOfServers.add( new ServerInfo(4,300));
listOfServers.add( new ServerInfo(5,300));
listOfServers.add( new ServerInfo(6,256));
listOfServers.add( new ServerInfo(7,265));
listOfServers.add( new ServerInfo(8,289));
listOfServers.add( new ServerInfo(9,310));
}
public static void main( String[] args){
Sample s = new Sample();
s.insertIntoList();
ServerInfoComparator com = new ServerInfoComparator();
Collections.sort(s.listOfServers,com);
for( ServerInfo server: s.listOfServers){
System.out.println(server);
}
}
}
我使用上面的代码根据serverDataRate按降序对元素进行排序。假设我在列表中有100个元素的更大样本集,并且代码必须每5-10秒执行一次,那么样本集非常小。这是对列表进行排序的最快方法,还是有一种我不知道的更快的方法?
答案 0 :(得分:12)
我改变了你的考试
private final List<ServerInfo> listOfServers = new ArrayList<ServerInfo>();
public void insertIntoList() {
for (int i = 0; i < 1000000; i++)
listOfServers.add(new ServerInfo(i, (int) (200 + Math.random() * 200)));
}
public static void main(String[] args) {
MyApp s = new MyApp();
s.insertIntoList();
ServerInfoComparator com = new ServerInfoComparator();
long start = System.nanoTime();
Collections.sort(s.listOfServers, com);
long time = System.nanoTime() - start;
System.out.printf("Sorting %,d took %.3f seconds%n", s.listOfServers.size(), time/1e9);
for (ServerInfo server : s.listOfServers) {
// System.out.println(server);
}
}
并打印
Sorting 1,000,000 took 0.438 seconds
那要快一点;)
顺便说一句:我将double
字段更改为int
。
答案 1 :(得分:3)
除非您的比较步骤非常重(看起来不像),否则100个元素不是很大的集合。在任何稍微现代化的机器中,100个元素将快速排序极。
话虽如此,我认为你的方法非常接近标准,我不会担心尝试优化它,除非你真的最终需要它。
早期优化是许多搞砸的父亲(假设是母亲)。
答案 2 :(得分:2)
您不需要在类中使用方法调用,即使该字段是私有的并不总是已知的 - private限制对类的访问,而不是对象的访问。
由于您的方法只返回属性,因此您可以直接使用该属性:
@Override
public int compare(ServerInfo o1, ServerInfo o2) {
/*
double datarate1=o1.getServerDataRate ();
double datarate2=o2.getServerDataRate ();
*/
double datarate1=o1.serverDataRate;
double datarate2=o2.serverDataRate;
if (datarate1 > datarate2)
return -1;
else if ( datarate1 < datarate2)
return +1;
else
return 0;
}
但是JVM可能会优化函数调用,并且在100个元素的范围内,它几乎不可测量。
你的方法返回一个双 - 你可以解释为什么?
使用整数,您可以这样做:
@Override
public int compare (ServerInfo o1, ServerInfo o2) {
return o2.serverDataRate - o1.serverDataRate;
}
但是考虑int over-overrun和underrun问题的最极端值。
答案 3 :(得分:1)
这不正常。检查你的计时方式。
long start = System.nanoTime();
// Sort here
long time = System.nanoTime() - start;
System.out.println(time / 1000000L + " Milliseconds");
答案 4 :(得分:1)
鉴于您没有经常排序,速度不应成为问题。即使有数千个项目,Collections.sort也非常快。
您是否尝试过应用程序以查看速度是否存在问题?过早优化不是一个好主意:))
警惕您的代码有一点:除非您确保所有服务器的dataRates
在排序过程中不会发生变化,否则您可能会得到不一致的结果!您应该同步方法,以便在整个列表排序之前datarates
不会更改。
答案 5 :(得分:0)
您可以使用数据结构以更快的方式完成排序。
BST(二进制搜索树)或TRIE将帮助您以更快的方式对大量数据进行排序。
它们需要一些冗长的代码,但如果数据集很大,它将帮助你在日志中运行。
答案 6 :(得分:0)
首先,您的serverDataRate变量类型是int。但是getter方法返回类型是double。当比较器工作时,所有getServerDataRate方法都将字段转换为更高的数据格式。如果getter方法的返回类型与字段类型相同,那么比较时间将更短。 第二,如果您的任务是简单的操作,则无需使用if(),在比较方法中。只需使用减法。像这样:
the getter:
public int getServerDataRate() {
return serverDataRate;
}
in comparator:
return o1.getServerDataRate()-o2.getServerDataRate(); // from smallest to largest value
or
return o2.getServerDataRate()-o1.getServerDataRate(); // from largest to smallest value