Skip to content

Instantly share code, notes, and snippets.

@dmelcer9
Created September 3, 2015 23:18
Show Gist options
  • Save dmelcer9/ab02af568e82124cc3ea to your computer and use it in GitHub Desktop.
Save dmelcer9/ab02af568e82124cc3ea to your computer and use it in GitHub Desktop.
Faster and More Readable than RecursiveQuicksort
import java.util.*;
public class ExampleUsage {
static final int LIST_SIZE = 1000000; //size of list
//Requires about 250-300MB of RAM per million list entries
//Has only been tested with random lists, may require more with sorted lists
public static void main(String[] args) {
long beginTime = System.nanoTime();
List<Integer> randomList = new ArrayList<>(LIST_SIZE);
Random r = new Random();
for(int i = 0;i<LIST_SIZE;i++){ //populate list with random integers
randomList.add(r.nextInt(1000000));
}
long listCreatedTime = System.nanoTime();
System.out.println("List created in " + ((double)listCreatedTime-(double)beginTime)/1000000000 + " seconds.");
Comparator<Integer> comparator = (i,j)->(i-j); //lambda expression for simple comparator
ForkJoinSort<Integer> sorter = new ForkJoinSort<>(randomList,comparator);
List<Integer> sortedList = sorter.invoke(); //sort the list
long sortDoneTime = System.nanoTime();
System.out.println("List sorted in " + ((double)sortDoneTime-(double)listCreatedTime)/1000000000 + " seconds.");
}
}
import java.util.*;
import java.util.concurrent.RecursiveTask;
public class ForkJoinSort<V> extends RecursiveTask<List<V>> {
protected final List<V> inputList;
protected final Comparator<V> comparator;
public ForkJoinSort(List<V> inputList, Comparator<V> comparator){
this.inputList = inputList;
this.comparator = comparator;
}
protected List<V> compute(){
final int inputSize = inputList.size(); //Used for determining capacity of ArrayList and whether to return
if(inputSize<=1){
return inputList;
}
final V pivot = inputList.get(inputSize/2); //Arbitrarily chosen pivot, but won't die on sorted lists
final List<V> belowList = new ArrayList<V>(inputSize);//ArrayLists work faster than LinkedLists if they are the right size
final List<V> equalsList = new ArrayList<V>(inputSize);
final List<V> aboveList = new ArrayList<V>(inputSize);
for(V current : inputList){
int compareResult = comparator.compare(current, pivot);
//Determine where to put result
if(compareResult < 0) belowList.add(current);
else if(compareResult > 0) aboveList.add(current);
else if(compareResult == 0) equalsList.add(current);
else assert false : "Categorization of list elements failed"; //Should never happen, run with -ea flag to enable assertions
}
final ForkJoinSort<V> belowSort = new ForkJoinSort<>(belowList, comparator);
final ForkJoinSort<V> aboveSort = new ForkJoinSort<>(aboveList, comparator);
final List<V> returnList = new LinkedList<V>();
aboveSort.fork();//Begin execution of aboveSort
returnList.addAll(belowSort.compute());//Execute belowSort
returnList.addAll(equalsList);
returnList.addAll(aboveSort.join());//Wait until aboveSort is finished and join it
return returnList;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment