Skip to content

Commit fb00ab2

Browse files
committed
2 parents 28256e7 + fbd14ad commit fb00ab2

File tree

3 files changed

+82
-23
lines changed

3 files changed

+82
-23
lines changed

src/main/java/com/github/coderodde/util/ParallelRadixSort.java

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,59 @@ public final class ParallelRadixSort {
3636
* The array slices smaller than this number of elements will be sorted with
3737
* merge sort.
3838
*/
39-
static final int MERGESORT_THRESHOLD = 4096;
39+
static final int DEFAULT_MERGESORT_THRESHOLD = 4096;
4040

4141
/**
4242
* The array slices smaller than this number of elements will be sorted with
4343
* insertion sort.
4444
*/
45-
static final int INSERTION_SORT_THRESHOLD = 16;
45+
static final int DEFAULT_INSERTION_SORT_THRESHOLD = 16;
4646

4747
/**
4848
* The minimum workload for a thread.
4949
*/
50-
private static final int THREAD_THRESHOLD = 65536;
50+
private static final int DEFAULT_THREAD_THRESHOLD = 65536;
51+
52+
/**
53+
* Minimum mergesort threshold.
54+
*/
55+
private static final int MINIMUM_MERGESORT_THRESHOLD = 7;
56+
57+
/**
58+
* Minimum insertion sort threshold.
59+
*/
60+
private static final int MINIMUM_INSERTION_SORT_THRESHOLD = 7;
61+
62+
/**
63+
* Minimum thread workload.
64+
*/
65+
private static final int MINIMUM_THREAD_WORKLOAD = 4001;
66+
67+
private static int insertionSortThreshold = DEFAULT_INSERTION_SORT_THRESHOLD;
68+
private static int mergesortThreshold = DEFAULT_MERGESORT_THRESHOLD;
69+
private static int threadWorkload = DEFAULT_THREAD_THRESHOLD;
70+
71+
public static void setInsertionSortThreshold(
72+
int newInsertionSortThreshold) {
73+
insertionSortThreshold =
74+
Math.max(
75+
newInsertionSortThreshold,
76+
MINIMUM_INSERTION_SORT_THRESHOLD);
77+
}
78+
79+
public static void setMergesortThreshold(int newMergesortThreshold) {
80+
mergesortThreshold =
81+
Math.max(
82+
newMergesortThreshold,
83+
MINIMUM_MERGESORT_THRESHOLD);
84+
}
85+
86+
public static void setThreadWorkload(int newThreadWorkload) {
87+
threadWorkload =
88+
Math.max(
89+
MINIMUM_THREAD_WORKLOAD,
90+
newThreadWorkload);
91+
}
5192

5293
public static void parallelSort(int[] array) {
5394
parallelSort(array, 0, array.length);
@@ -62,14 +103,14 @@ public static void parallelSort(int[] array, int fromIndex, int toIndex) {
62103
return;
63104
}
64105

65-
if (rangeLength <= INSERTION_SORT_THRESHOLD) {
106+
if (rangeLength <= insertionSortThreshold) {
66107
insertionSort(array, fromIndex, rangeLength);
67108
return;
68109
}
69110

70111
int[] buffer = new int[rangeLength];
71112

72-
if (rangeLength <= MERGESORT_THRESHOLD) {
113+
if (rangeLength <= mergesortThreshold) {
73114
mergesort(
74115
array,
75116
buffer,
@@ -84,7 +125,7 @@ public static void parallelSort(int[] array, int fromIndex, int toIndex) {
84125
int threads =
85126
Math.min(
86127
Runtime.getRuntime().availableProcessors(),
87-
rangeLength / THREAD_THRESHOLD);
128+
rangeLength / threadWorkload);
88129

89130
threads = Math.max(threads, 1);
90131

@@ -172,7 +213,7 @@ private static void radixSortImpl(int[] source,
172213
int rangeLength,
173214
int recursionDepth) {
174215

175-
if (rangeLength <= MERGESORT_THRESHOLD) {
216+
if (rangeLength <= mergesortThreshold) {
176217
mergesort(
177218
source,
178219
target,
@@ -235,7 +276,7 @@ private static void radixSortImpl(int[] source,
235276
target,
236277
source,
237278
startIndexMap[i],
238-
startIndexMap[i] + bucketSizeMap[i],
279+
startIndexMap[i],
239280
bucketSizeMap[i],
240281
recursionDepth + 1);
241282
}
@@ -254,18 +295,17 @@ private static void mergesort(int[] source,
254295
int[] t = target;
255296
int sFromIndex = sourceFromIndex;
256297
int tFromIndex = targetFromIndex;
257-
int runs = rangeLength / INSERTION_SORT_THRESHOLD;
298+
int runs = rangeLength / insertionSortThreshold;
258299

259300
for (int i = 0; i != runs; ++i) {
260-
insertionSort(
261-
source,
301+
insertionSort(source,
262302
offset,
263-
INSERTION_SORT_THRESHOLD);
303+
insertionSortThreshold);
264304

265-
offset += INSERTION_SORT_THRESHOLD;
305+
offset += insertionSortThreshold;
266306
}
267307

268-
if (rangeLength % INSERTION_SORT_THRESHOLD != 0) {
308+
if (rangeLength % insertionSortThreshold != 0) {
269309
// Sort the rightmost run that is smaller than
270310
// INSERTION_SORT_THRESHOLD elements.
271311
insertionSort(
@@ -276,7 +316,7 @@ private static void mergesort(int[] source,
276316
runs++;
277317
}
278318

279-
int runWidth = INSERTION_SORT_THRESHOLD;
319+
int runWidth = insertionSortThreshold;
280320
int passes = 0;
281321

282322
while (runs != 1) {

src/main/java/com/github/coderodde/util/Utils.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@ public final class Utils {
66

77
private static final int MAX_VALUE = 1000;
88

9-
public static int[] createRandomIntArray(int size, Random random) {
9+
public static int[] createRandomIntArray(
10+
int size,
11+
int maxValue,
12+
Random random) {
13+
1014
int[] a = new int[size];
1115

1216
for (int i = 0; i < size; i++) {
13-
a[i] = random.nextInt(MAX_VALUE + 1);
17+
a[i] = random.nextInt(maxValue);
1418
}
1519

1620
return a;
1721
}
22+
23+
public static int[] createRandomIntArray(int size, Random random) {
24+
return createRandomIntArray(size, MAX_VALUE, random);
25+
}
1826
}

src/test/java/com/github/coderodde/util/ParallelRadixSortTest.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@
44
import java.util.Random;
55
import static org.junit.Assert.assertEquals;
66
import static org.junit.Assert.assertTrue;
7+
import org.junit.BeforeClass;
78
import org.junit.Test;
89

910
public final class ParallelRadixSortTest {
1011

12+
@BeforeClass
13+
public static void setupBeforeClass() {
14+
ParallelRadixSort.setInsertionSortThreshold(-1);
15+
ParallelRadixSort.setMergesortThreshold(-1);
16+
}
17+
1118
@Test
1219
public void testInsertionSort() {
1320
Random random = new Random(13L);
@@ -49,12 +56,16 @@ public void testMergesort() {
4956
@Test
5057
public void testSerialRadixSort() {
5158
Random random = new Random(26);
52-
final int SIZE = 50_000;
53-
int[] array1 = Utils.createRandomIntArray(SIZE, random);
59+
final int SIZE = 128;
60+
int[] array1 = Utils.createRandomIntArray(
61+
SIZE,
62+
Integer.MAX_VALUE - 1,
63+
random);
64+
5465
int[] array2 = array1.clone();
5566

56-
final int FROM_INDEX = 20;
57-
final int TO_INDEX = SIZE - 20;
67+
final int FROM_INDEX = 14;
68+
final int TO_INDEX = SIZE - 14;
5869

5970
Arrays.sort(array1, FROM_INDEX, TO_INDEX);
6071
ParallelRadixSort.parallelSort(
@@ -73,7 +84,7 @@ public void bruteForceTestInsertionsort() {
7384
for (int iteration = 0; iteration < ITERATIONS; iteration++) {
7485
int arrayLength =
7586
random.nextInt(
76-
ParallelRadixSort.INSERTION_SORT_THRESHOLD + 1);
87+
ParallelRadixSort.DEFAULT_INSERTION_SORT_THRESHOLD + 1);
7788

7889
int[] array1 = Utils.createRandomIntArray(arrayLength, random);
7990
int[] array2 = array1.clone();
@@ -118,7 +129,7 @@ public void bruteForceTestMergesort() {
118129
for (int iteration = 0; iteration < ITERATIONS; iteration++) {
119130
int arrayLength =
120131
random.nextInt(
121-
ParallelRadixSort.MERGESORT_THRESHOLD + 1);
132+
ParallelRadixSort.DEFAULT_MERGESORT_THRESHOLD + 1);
122133

123134
int[] array1 = Utils.createRandomIntArray(arrayLength, random);
124135
int[] array2 = array1.clone();

0 commit comments

Comments
 (0)