Created
September 3, 2015 23:18
-
-
Save dmelcer9/ab02af568e82124cc3ea to your computer and use it in GitHub Desktop.
Faster and More Readable than RecursiveQuicksort
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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."); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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