|
|
@@ -1,4 +1,5 @@ |
|
|
|
import java.util.LinkedList; |
|
|
|
import java.util.Random; |
|
|
|
|
|
|
|
/** Timing class: measure big-O complexity and runtime of data structures. |
|
|
|
* |
|
|
@@ -14,26 +15,142 @@ public class Timing { |
|
|
|
// Tests |
|
|
|
public static void main(String[] args) { |
|
|
|
linked_list_add_test(); |
|
|
|
linked_list_add_remove_test(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Compare the add and remove method - adding and removing from list. |
|
|
|
* |
|
|
|
* NOTE: If this is not constant, then add is not O(1) amortized, |
|
|
|
* and there is something wrong with your implementation. |
|
|
|
* */ |
|
|
|
public static void linked_list_add_remove_test() { |
|
|
|
StringBuffer sb = new StringBuffer(); |
|
|
|
|
|
|
|
sb.append("N, Add Remove Amortized Walltime Per 1k Builtin (us), Add Remove Amortized Walltime Per 1k SLL (us), Add Remove Amortized Walltime Per 1k DLL (us) \n"); |
|
|
|
|
|
|
|
int ntrials = 1000; |
|
|
|
Random r; |
|
|
|
|
|
|
|
// Loop over values of N |
|
|
|
for(int N = (int)(1E3); N <= (int)(1E6); N*=4) { |
|
|
|
|
|
|
|
sb.append( String.format("%d, ",N) ); |
|
|
|
|
|
|
|
|
|
|
|
// builtin linked list: |
|
|
|
// |
|
|
|
// b prefix is for built-in datatype |
|
|
|
Tim btim = new Tim(); |
|
|
|
|
|
|
|
// Trials counter is always k for Kafka |
|
|
|
for(int k = 0; k<ntrials; k++) { |
|
|
|
// Each trial is a different sequence of random numbers, |
|
|
|
// but the sequence matches between tests of different collection types |
|
|
|
r = new Random(k); |
|
|
|
LinkedList<Integer> blist = new LinkedList<Integer>(); |
|
|
|
for(int i=0; i<N; i++) { |
|
|
|
// 75% of the time, we add something. 25% of the time, we remove something. |
|
|
|
boolean addSomething = r.nextBoolean(); |
|
|
|
if(addSomething) { |
|
|
|
blist.add(0,r.nextInt(100)); |
|
|
|
} else { |
|
|
|
if(!blist.isEmpty()) { |
|
|
|
blist.remove(0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
double btime_total = btim.elapsedms(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// my little singly linked list: |
|
|
|
// |
|
|
|
// m prefix is for mine |
|
|
|
Tim mtim = new Tim(); |
|
|
|
|
|
|
|
for(int k=0; k<ntrials; k++) { |
|
|
|
// reproducible random numbers across tests |
|
|
|
r = new Random(k); |
|
|
|
TLinkedList<Integer> mylist = new TLinkedList<Integer>(); |
|
|
|
for(int i=0; i<N; i++) { |
|
|
|
// 75% of the time, we add something. 25% of the time, we remove something. |
|
|
|
boolean addSomething = r.nextBoolean(); |
|
|
|
if(addSomething) { |
|
|
|
mylist.addFirst(r.nextInt(100)); |
|
|
|
} else { |
|
|
|
if(!mylist.isEmpty()) { |
|
|
|
mylist.removeFirst(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
double mtime_total = mtim.elapsedms(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// doubly linked list: |
|
|
|
// |
|
|
|
// d prefix is for doubly |
|
|
|
Tim dtim = new Tim(); |
|
|
|
|
|
|
|
for(int k=0; k<ntrials; k++) { |
|
|
|
r = new Random(k); |
|
|
|
TLinkedList<Integer> dlist = new TLinkedList<Integer>(); |
|
|
|
for(int i=0; i<N; i++) { |
|
|
|
// 75% of the time, we add something. 25% of the time, we remove something. |
|
|
|
boolean addSomething = r.nextBoolean(); |
|
|
|
if(addSomething) { |
|
|
|
dlist.addFirst(r.nextInt(100)); |
|
|
|
} else { |
|
|
|
if(!dlist.isEmpty()) { |
|
|
|
dlist.removeFirst(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
double dtime_total = dtim.elapsedms(); |
|
|
|
|
|
|
|
// print amortized cost per 1000 operations, times 1000 ms -> us |
|
|
|
sb.append( String.format("%.3f, ", btime_total/N*1000) ); |
|
|
|
sb.append( String.format("%.3f, ", mtime_total/N*1000) ); |
|
|
|
sb.append( String.format("%.3f ", dtime_total/N*1000) ); |
|
|
|
|
|
|
|
|
|
|
|
sb.append("\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
System.out.println(sb.toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Compare the add method - appending to the rear of a list. |
|
|
|
* |
|
|
|
* Compares builtin LinkedList type with self-authored TLinkedList class. |
|
|
|
* |
|
|
|
* NOTE: If this is not constant, then add is not O(1) amortized, |
|
|
|
* and there is something wrong with your implementation. |
|
|
|
* */ |
|
|
|
public static void linked_list_add_test() { |
|
|
|
|
|
|
|
StringBuffer sb = new StringBuffer(); |
|
|
|
|
|
|
|
System.out.println("N, Walltime Builtin (s), Walltime Mine (s)"); |
|
|
|
sb.append("N, Add Amortized Walltime Per 1k Builtin (us), Add Amortized Walltime Per 1k SLL (us), Add Amortized Walltime Per 1k DLL (us) \n"); |
|
|
|
|
|
|
|
int ntrials = 1000; |
|
|
|
|
|
|
|
// Loop over some values of N, and print the amortized operational cost. |
|
|
|
for(int N = 1024; N < 1E6; N*=2) { |
|
|
|
|
|
|
|
int ntrials = 1000; |
|
|
|
|
|
|
|
// Hold on to your butts. |
|
|
|
|
|
|
|
System.out.printf("%d, ", N); |
|
|
|
// Loop over some values of N, |
|
|
|
// print the total cost, |
|
|
|
// print the cost per add operation |
|
|
|
for(int N = 1024; N < 5e5; N *= 2) { |
|
|
|
|
|
|
|
|
|
|
|
// builtin linked list: |
|
|
@@ -49,12 +166,9 @@ public class Timing { |
|
|
|
blist.add(i*i); |
|
|
|
} |
|
|
|
} |
|
|
|
double btime_total = btim.elapsed(); |
|
|
|
|
|
|
|
System.out.printf("%.2f,", btime_total); |
|
|
|
|
|
|
|
double btime_total = btim.elapsedms(); |
|
|
|
|
|
|
|
// my little linked list: |
|
|
|
// singly linked list: |
|
|
|
// |
|
|
|
// m prefix is for mine |
|
|
|
Tim mtim = new Tim(); |
|
|
@@ -66,11 +180,36 @@ public class Timing { |
|
|
|
mylist.addLast(i*i); |
|
|
|
} |
|
|
|
} |
|
|
|
double mtime_total = mtim.elapsed(); |
|
|
|
System.out.printf("%.2f \n", mtime_total); |
|
|
|
double mtime_total = mtim.elapsedms(); |
|
|
|
|
|
|
|
|
|
|
|
// doubly linked list: |
|
|
|
Tim dtim = new Tim(); |
|
|
|
|
|
|
|
// Trials counter is k |
|
|
|
for(int k=0; k<ntrials; k++) { |
|
|
|
TLinkedList<Integer> dlist = new TLinkedList<Integer>(); |
|
|
|
for(int i=0; i<N; i++) { |
|
|
|
dlist.addLast(i*i); |
|
|
|
} |
|
|
|
} |
|
|
|
double dtime_total = dtim.elapsedms(); |
|
|
|
|
|
|
|
|
|
|
|
// Print out the data in CSV format: |
|
|
|
|
|
|
|
// N |
|
|
|
sb.append( String.format("%d, ", N) ); |
|
|
|
|
|
|
|
// print cost per 1000 add operations us, times 100 ms -> us |
|
|
|
sb.append( String.format("%.3f, ", btime_total/N*1000) ); |
|
|
|
sb.append( String.format("%.3f, ", mtime_total/N*1000) ); |
|
|
|
sb.append( String.format("%.3f ", btime_total/N*1000) ); |
|
|
|
sb.append("\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
System.out.println(sb.toString()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|