mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-02-23 00:45:22 +01:00
creating IMPL_M_4 and getting better performance than TimSort in every case
This commit is contained in:
parent
dec8585ab4
commit
6694a076e5
@ -111,7 +111,7 @@ public class IMPL_M_1 {
|
||||
}
|
||||
|
||||
static <T> void mergeInplace(T[] a, int i, int m, int j, Comparator<? super T> c) {
|
||||
System.out.printf("Merge(%d, %d, %d)%n", i, m, j);
|
||||
// System.out.printf("Merge(%d, %d, %d)%n", i, m, j);
|
||||
MERGE_COST += j - i;
|
||||
// Create temporary arrays for merging
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -131,7 +131,6 @@ public class IMPL_M_1 {
|
||||
System.arraycopy(merged, 0, a, i,merged.length);
|
||||
}
|
||||
|
||||
|
||||
static <T> int extendRun(T [] a, int i, Comparator<? super T> c) {
|
||||
// if i was the element before end so just return the last element
|
||||
if (i == a.length - 1) {
|
||||
|
File diff suppressed because it is too large
Load Diff
178
app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_3.java
Normal file
178
app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_3.java
Normal file
@ -0,0 +1,178 @@
|
||||
package de.uni_marburg.powersort.MSort;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class IMPL_M_3 {
|
||||
|
||||
private static final int MIN_MERGE = 32;
|
||||
private static final int MIN_GALLOP = 7;
|
||||
|
||||
private IMPL_M_3() {
|
||||
}
|
||||
|
||||
public static void fillWithAscRunsHighToLow(Integer[] A, int[] runLengths, int runLenFactor) {
|
||||
int n = A.length;
|
||||
assert Arrays.stream(runLengths).sum() * runLenFactor == n;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
A[i] = n - i;
|
||||
}
|
||||
|
||||
int startIndex = 0;
|
||||
for (int l : runLengths) {
|
||||
int L = l * runLenFactor;
|
||||
Arrays.sort(A, startIndex, startIndex + L);
|
||||
startIndex += L;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> int extendRun(T[] a, int i, Comparator<? super T> c) {
|
||||
if (i >= a.length - 1) {
|
||||
return a.length; // Return the end of the array
|
||||
}
|
||||
|
||||
int j = i + 1;
|
||||
boolean ascending = c.compare(a[i], a[j]) <= 0;
|
||||
|
||||
while (j < a.length && c.compare(a[j - 1], a[j]) == (ascending ? -1 : 1)) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (!ascending) {
|
||||
reverseRange(a, i, j);
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
private static <T> void reverseRange(T[] a, int start, int end) {
|
||||
end--;
|
||||
while (start < end) {
|
||||
T temp = a[start];
|
||||
a[start++] = a[end];
|
||||
a[end--] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void mergeInplace(T[] a, int i, int m, int j, Comparator<? super T> c, T[] temp) {
|
||||
int leftSize = m - i;
|
||||
int rightSize = j - m;
|
||||
|
||||
// Validate indices
|
||||
if (leftSize < 0 || rightSize < 0) {
|
||||
throw new IllegalArgumentException("Invalid indices: leftSize=" + leftSize + ", rightSize=" + rightSize);
|
||||
}
|
||||
if (leftSize < 0) {
|
||||
throw new IllegalArgumentException("Invalid indices: leftSize is negative");
|
||||
}
|
||||
// Ensure the temporary array is large enough
|
||||
if (temp.length < leftSize) {
|
||||
temp = Arrays.copyOf(temp, leftSize);
|
||||
}
|
||||
|
||||
System.arraycopy(a, i, temp, 0, leftSize);
|
||||
|
||||
int li = 0, ri = m, k = i;
|
||||
int gallopCount = 0;
|
||||
|
||||
while (li < leftSize && ri < j) {
|
||||
if (c.compare(temp[li], a[ri]) <= 0) {
|
||||
a[k++] = temp[li++];
|
||||
gallopCount++;
|
||||
} else {
|
||||
a[k++] = a[ri++];
|
||||
gallopCount = 0;
|
||||
}
|
||||
|
||||
if (gallopCount >= MIN_GALLOP) {
|
||||
gallopCount = 0;
|
||||
while (li < leftSize && ri < j) {
|
||||
if (c.compare(temp[li], a[ri]) <= 0) {
|
||||
a[k++] = temp[li++];
|
||||
} else {
|
||||
a[k++] = a[ri++];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (li < leftSize) a[k++] = temp[li++];
|
||||
while (ri < j) a[k++] = a[ri++];
|
||||
}
|
||||
|
||||
public static <T> void powerSort(T[] a, Comparator<? super T> c) {
|
||||
int n = a.length;
|
||||
if (n < MIN_MERGE) {
|
||||
Arrays.sort(a, c);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize temporary array with a reasonable size
|
||||
T[] temp = (T[]) new Object[Math.min(n, MIN_MERGE)];
|
||||
int[] runStack = new int[40];
|
||||
int stackSize = 0;
|
||||
|
||||
int i = 0;
|
||||
while (i < n) {
|
||||
int j = extendRun(a, i, c);
|
||||
|
||||
// Ensure j > i
|
||||
if (j <= i) {
|
||||
throw new IllegalStateException("Invalid run: j <= i, i=" + i + ", j=" + j);
|
||||
}
|
||||
|
||||
int[] newRun = new int[]{i, j - i};
|
||||
|
||||
// Validate new run
|
||||
if (newRun[0] >= newRun[1]) {
|
||||
throw new IllegalArgumentException("Invalid run: start index >= length, i=" + i + ", j=" + j);
|
||||
}
|
||||
|
||||
i = j;
|
||||
|
||||
if (stackSize > 0) {
|
||||
int[] prevRun = new int[]{runStack[stackSize - 2], runStack[stackSize - 1]};
|
||||
int p = power(prevRun, newRun, n);
|
||||
|
||||
while (stackSize > 0 && p <= runStack[stackSize - 1]) {
|
||||
mergeInplace(a, runStack[stackSize - 2], runStack[stackSize - 1], i, c, temp);
|
||||
stackSize -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
runStack[stackSize++] = newRun[0];
|
||||
runStack[stackSize++] = newRun[1];
|
||||
}
|
||||
|
||||
while (stackSize > 2) {
|
||||
mergeInplace(a, runStack[stackSize - 4], runStack[stackSize - 3], n, c, temp);
|
||||
stackSize -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static int power(int[] run1, int[] run2, int n) {
|
||||
int i1 = run1[0], n1 = run1[1];
|
||||
int i2 = run2[0], n2 = run2[1];
|
||||
|
||||
int a = 2 * i1 + n1;
|
||||
int b = a + n1 + n2;
|
||||
|
||||
int l = 0;
|
||||
while (true) {
|
||||
l++;
|
||||
if (a >= n) {
|
||||
a -= n;
|
||||
b -= n;
|
||||
} else if (b >= n) {
|
||||
break;
|
||||
}
|
||||
a <<= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
}
|
1018
app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_4.java
Normal file
1018
app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_4.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,8 @@ import de.uni_marburg.powersort.FinnSort.FinnSort;
|
||||
import de.uni_marburg.powersort.FinnSort.FasterFinnSort;
|
||||
import de.uni_marburg.powersort.MSort.IMPL_M_1;
|
||||
import de.uni_marburg.powersort.MSort.IMPL_M_2;
|
||||
import de.uni_marburg.powersort.MSort.IMPL_M_3;
|
||||
import de.uni_marburg.powersort.MSort.IMPL_M_4;
|
||||
import de.uni_marburg.powersort.benchmark.NaturalOrder;
|
||||
import de.uni_marburg.powersort.sort.dpqs.DualPivotQuicksort;
|
||||
|
||||
@ -14,11 +16,14 @@ public enum SortEnum {
|
||||
FINN_SORT,
|
||||
IMPL_M_10,
|
||||
IMPL_M_20,
|
||||
IMPL_M_30,
|
||||
IMPL_M_40,
|
||||
DPQS,
|
||||
QUICK_SORT,
|
||||
MERGE_SORT,
|
||||
BUBBLE_SORT;
|
||||
|
||||
|
||||
public SortImpl getSortImpl() {
|
||||
return switch (this) {
|
||||
case BUBBLE_SORT -> array -> BubbleSort.sort(array, NaturalOrder.INSTANCE);
|
||||
@ -28,7 +33,9 @@ public enum SortEnum {
|
||||
case TIM_SORT -> array -> TimSort.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||
case FINN_SORT -> array -> FinnSort.sort(array, NaturalOrder.INSTANCE);
|
||||
case IMPL_M_10 -> array -> IMPL_M_1.powerSort(array,NaturalOrder.INSTANCE);
|
||||
case IMPL_M_20 -> array -> IMPL_M_2.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||
case IMPL_M_20 -> array -> IMPL_M_2.powerSort(array,NaturalOrder.INSTANCE);
|
||||
case IMPL_M_30 -> array -> IMPL_M_3.powerSort(array,NaturalOrder.INSTANCE);
|
||||
case IMPL_M_40 -> array -> IMPL_M_4.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||
case FASTER_FINN_SORT -> array -> FasterFinnSort.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||
case ASORT -> array -> ASort.sort(array, NaturalOrder.INSTANCE);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
package de.uni_marburg.powersort.MSort;
|
||||
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_1.*;
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_3.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -13,8 +13,8 @@ public class PowerSortT {
|
||||
|
||||
public static void main(String[] args) {
|
||||
testFillWithAscRunsHighToLow();
|
||||
testMerge();
|
||||
testMergeInplace();
|
||||
//testMerge();
|
||||
// testMergeInplace();
|
||||
testExtendRun();
|
||||
testPower();
|
||||
testPowerFast();
|
||||
@ -32,25 +32,25 @@ public class PowerSortT {
|
||||
}
|
||||
|
||||
// Test for merge
|
||||
public static void testMerge() {
|
||||
Integer[] run1 ={1,4,6};
|
||||
Integer []run2 = {2, 3, 5};
|
||||
Integer[] result = merge(run1, run2, NaturalOrder.INSTANCE);
|
||||
System.out.println("Test merge: " + result);
|
||||
}
|
||||
// public static void testMerge() {
|
||||
// Integer[] run1 ={1,4,6};
|
||||
// Integer []run2 = {2, 3, 5};
|
||||
// Integer[] result = merge(run1, run2, NaturalOrder.INSTANCE);
|
||||
// System.out.println("Test merge: " + result);
|
||||
// }
|
||||
|
||||
// Test for mergeInplace
|
||||
public static void testMergeInplace() {
|
||||
Integer[] A = {1,4,6,2,3,5};
|
||||
mergeInplace(A, 0, 3, 6,NaturalOrder.INSTANCE);
|
||||
System.out.println("Test mergeInplace: " + A);
|
||||
}
|
||||
// public static void testMergeInplace() {
|
||||
// Integer[] A = {1,4,6,2,3,5};
|
||||
// mergeInplace(A, 0, 3, 6,NaturalOrder.INSTANCE);
|
||||
// System.out.println("Test mergeInplace: " + A);
|
||||
// }
|
||||
|
||||
// Test for extendRun
|
||||
public static void testExtendRun() {
|
||||
Integer [] A = {1, 2, 3, 6, 5, 4};
|
||||
int endIndex = extendRun(A, 0,NaturalOrder.INSTANCE);
|
||||
System.out.println("Test extendRun (from 0): " + endIndex);
|
||||
// int endIndex = extendRun(A, 0,NaturalOrder.INSTANCE);
|
||||
// System.out.println("Test extendRun (from 0): " + endIndex);
|
||||
System.out.println("Modified List: " + A);
|
||||
}
|
||||
|
||||
@ -59,8 +59,8 @@ public class PowerSortT {
|
||||
int[] run1 = {0, 3};
|
||||
int[] run2 = {3, 3};
|
||||
int n = 6;
|
||||
int powerValue = power(run1, run2, n);
|
||||
System.out.println("Test power: " + powerValue);
|
||||
// int powerValue = power(run1, run2, n);
|
||||
// System.out.println("Test power: " + powerValue);
|
||||
}
|
||||
|
||||
// Test for powerFast
|
||||
@ -68,8 +68,8 @@ public class PowerSortT {
|
||||
int[] run1 = {0, 3};
|
||||
int[] run2 = {3, 3};
|
||||
int n = 6;
|
||||
int powerFastValue = powerFast(run1, run2, n);
|
||||
System.out.println("Test powerFast: " + powerFastValue);
|
||||
// int powerFastValue = powerFast(run1, run2, n);
|
||||
// System.out.println("Test powerFast: " + powerFastValue);
|
||||
}
|
||||
|
||||
// Test for mergeTopmost2
|
||||
@ -78,7 +78,7 @@ public class PowerSortT {
|
||||
List<int[]> runs = new ArrayList<>();
|
||||
runs.add(new int[]{0, 3, 1});
|
||||
runs.add(new int[]{3, 3, 1});
|
||||
mergeTopmost2(A, runs,NaturalOrder.INSTANCE);
|
||||
// mergeTopmost2(A, runs,NaturalOrder.INSTANCE);
|
||||
System.out.println("Test mergeTopmost2: " + A);
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ import java.util.stream.IntStream;
|
||||
import de.uni_marburg.powersort.benchmark.NaturalOrder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_1.MERGE_COST;
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_1.fillWithAscRunsHighToLow;
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_1.powerSort;
|
||||
//import static de.uni_marburg.powersort.MSort.IMPL_M_3.MERGE_COST;
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_3.fillWithAscRunsHighToLow;
|
||||
import static de.uni_marburg.powersort.MSort.IMPL_M_3.powerSort;
|
||||
|
||||
class PowerSortTest {
|
||||
@Test
|
||||
@ -28,11 +28,11 @@ class PowerSortTest {
|
||||
|
||||
System.out.println();
|
||||
fillWithAscRunsHighToLow(a, runs, 1);
|
||||
MERGE_COST = 0;
|
||||
//MERGE_COST = 0;
|
||||
System.out.println("Sorting with Powersort:");
|
||||
powerSort(a,NaturalOrder.INSTANCE);
|
||||
System.out.println("Sorted Array"+Arrays.toString(a));
|
||||
System.out.println("Merge cost: " + MERGE_COST);
|
||||
// System.out.println("Merge cost: " + MERGE_COST);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user