问题
i'm working on an assignment about huge graphs and i have to construct the main graph (as adjacency list) from reading a .txt file which nearly has 5 billion lines.Actually, graph consists of 870k vertices. Whatever, i realized that there is a huge time difference ( more than 2 hours) between my first and second implementation. I'm curious about why there is such an unnegligible difference between these two implementations. Here you can see the main simple code about reading the txt file and constructing graph ;
public class KosarajusSCC {
private int t; // for finishing times in 1st pass
private int s; // for leaders in 2nd pass
private static final int N = 875714;
private LinkedList<Vertex> mainList;
public KosarajusSCC(){
this.t = 0;
this.s = 0;
this.mainList = new LinkedList<>();
}
public void contructMainGraph() throws FileNotFoundException{
Scanner reader = new Scanner(new File("src\\Assignment4\\SCC.txt"));
for (int i = 1; i <= N; i++) {
mainList.add(new Vertex(i));
}
StringTokenizer tokenizer;
String str;
int counter = 0;
// construct the adjaceny list of vertices
while(reader.hasNextLine()){
str = reader.nextLine();
tokenizer = new StringTokenizer(str);
int tailVertex = Integer.parseInt(tokenizer.nextToken());
int headVertex = Integer.parseInt(tokenizer.nextToken());
mainList.get(tailVertex-1).getAdjacencyList().add( mainList.get(headVertex-1));
}
reader.close();
}
}
So this contructMainGraph()
method takes more than 2 hours,however, if i use an array with size N instead of LinkedList,like ;
Vertex[] mainArray = new Vertex[N];
for (int i = 0; i < mainArray.length; i++) {
mainArray[i] = new Vertex(i+1);
}
and if i change the last statement of the while loop with;
mainArray[tailVertex-1].getAdjacencyList().add(mainArray[headVertex-1]);
then everything finishes in less than 10 seconds. So what does happen there ?. I will appreciated if you can help,and thanks anyway
EDIT: i forgot to share Vertex class :)
public class Vertex {
private int finishTime;
private int leader;
private boolean marked;
private int vertexID;
private LinkedList<Vertex> adjacencyList;
public Vertex(int vertexID){
this.vertexID = vertexID;
this.marked = false;
this.finishTime = 0;
this.leader = 0;
this.adjacencyList = new LinkedList<>();
}
// getters and setters here
}
回答1:
Because you're indexing into it. That's an O(n) operation on a linked-list, but O(1) on an array.
回答2:
I believe it comes down to Time complexity.
An array has a time complexity of O(1) for read. But when you use a Doubly Linked list would have a time complexity of O(n).
I would suggest my all time favorite ArrayList.
来源:https://stackoverflow.com/questions/17959489/huge-performance-difference-between-using-linkedlist-and-array-for-constructing