diff --git a/.idea/compiler.xml b/.idea/compiler.xml index cbd75e9..4ba6ee5 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -3,6 +3,16 @@ + + + + + + + + + + diff --git a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/JmhCgl.java b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/JmhCgl.java index 6f146b0..a58942e 100644 --- a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/JmhCgl.java +++ b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/JmhCgl.java @@ -22,8 +22,8 @@ public class JmhCgl extends JmhBase { CglEnum dataEnum; // Either all or a selection of sort implementations. - @Param() - //@Param({"TIM_SORT", "FASTER_FINN_SORT"}) + //@Param() + @Param({"TIM_SORT", "FINN_SORT", "IMPL_M_11"}) SortEnum sortEnum; @Override diff --git a/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_1.java b/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_1.java index bcfecb9..54b8ea4 100644 --- a/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_1.java +++ b/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_1.java @@ -2,10 +2,11 @@ package de.uni_marburg.powersort.MSort; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.stream.IntStream; -public class IMPL_M_1 > { +public class IMPL_M_1 { private IMPL_M_1() { } @@ -28,7 +29,6 @@ public class IMPL_M_1 > { */ protected static int MERGE_COST = 0; - public static void fillWithAscRunsHighToLow(List A, int[] runLengths, int runLenFactor) { //A has a fixed size, but it doesn't have any meaningful values int n = A.size(); @@ -54,55 +54,91 @@ public class IMPL_M_1 > { } - static > List merge(List run1, List run2) { + static List merge(List run1, List run2, Comparator c) { List result = new ArrayList<>(); while (!run1.isEmpty() && !run2.isEmpty()) { //This comparison only works if the lists are sorted - if (run1.get(0).compareTo(run2.get(0)) < 0) { - result.add(run1.remove(0)); + if (c.compare(run1.getFirst(),run2.getFirst()) < 0) { + result.add(run1.removeFirst()); } else { - result.add(run2.remove(0)); + result.add(run2.removeFirst()); } } - /// can be improved by finding out which one is empty and only add the other one + // can be improved by finding out which one is empty and only add the other one result.addAll(run1); result.addAll(run2); return result; } - static > void mergeInplace(List a, int i, int m, int j) { - // System.out.printf("Merge(%d, %d, %d)%n", i, m, j); - MERGE_COST += j - i; - List sublist = merge( - new ArrayList<>(a.subList(i, m)), - new ArrayList<>(a.subList(m, j)) - ); - for (int k = 0; k < sublist.size(); k++) { - a.set(i + k, sublist.get(k)); + // New helper method to handle range reversal + private static void reverseRange(T[] a, int start, int end) { + // end is exclusive, so we need to use end-1 as the right boundary + int left = start; + int right = end - 1; + while (left < right) { + T temp = a[left]; + a[left] = a[right]; + a[right] = temp; + left++; + right--; } } - static > int extendRun(List a, int i) { + static void mergeInplace(T[] a, int i, int m, int j, Comparator c) { + // System.out.printf("Merge(%d, %d, %d)%n", i, m, j); + MERGE_COST += j - i; +// Create temporary arrays for merging + @SuppressWarnings("unchecked") + T[] left = (T[]) new Object[m - i]; + @SuppressWarnings("unchecked") + T[] right = (T[]) new Object[j - m]; + + // Copy data to temporary arrays + System.arraycopy(a, i, left, 0, m - i); + System.arraycopy(a, m, right, 0, j - m); + + // Merge back to original array + int k = i, l = 0, r = 0; + while (l < left.length && r < right.length) { + if (c.compare(left[l], right[r]) <= 0) { + a[k++] = left[l++]; + } else { + a[k++] = right[r++]; + } + } + + // Copy remaining elements + while (l < left.length) { + a[k++] = left[l++]; + } + while (r < right.length) { + a[k++] = right[r++]; + } + } + + + static int extendRun(T [] a, int i, Comparator c) { // if i was the element before end so just return the last element - if (i == a.size() - 1) { + if (i == a.length - 1) { return i + 1; } //we're looking at the element next to a[i] int j = i + 1; - if (a.get(i).compareTo( a.get(j)) <=0) { - while (j < a.size() && a.get(j - 1).compareTo( a.get(j)) <= 0) { + if (c.compare(a[i],a[j]) <=0) { + while (j < a.length && c.compare(a[j - 1], a[j]) <= 0) { j++; } } else { - while (j < a.size() && a.get(j - 1).compareTo(a.get(j)) > 0) { + while (j < a.length && c.compare(a[j - 1],a[j]) > 0) { j++; } - List sublist = a.subList(i, j); - Collections.reverse(sublist); + // Reverse the decreasing sequence + reverseRange(a,i,j); } return j; } + public static int power(int[] run1, int[] run2, int n) { int i1 = run1[0], n1 = run1[1]; int i2 = run2[0], n2 = run2[1]; @@ -122,35 +158,35 @@ public class IMPL_M_1 > { return l; } - public static > void mergeTopmost2(List a, List runs) { + public static void mergeTopmost2(T[] a, List runs, Comparator c) { assert runs.size() >= 2; int[] Y = runs.get(runs.size() - 2); - int[] Z = runs.get(runs.size() - 1); + int[] Z = runs.getLast(); assert Z[0] == Y[0] + Y[1]; - mergeInplace(a, Y[0], Z[0], Z[0] + Z[1]); + mergeInplace(a, Y[0], Z[0], Z[0] + Z[1], c); runs.set(runs.size() - 2, new int[] {Y[0], Y[1] + Z[1], Y[2]}); runs.removeLast(); } - public static > void powerSort(List a) { - int n = a.size(); + public static void powerSort(T[] a, Comparator c) { + int n = a.length; int i = 0; List runs = new ArrayList<>(); - int j = extendRun(a, i); + int j = extendRun(a, i, c); runs.add(new int[] {i, j - i, 0}); i = j; while (i < n) { - j = extendRun(a, i); - int p = power(runs.get(runs.size() - 1), new int[] {i, j - i}, n); + j = extendRun(a, i, c); + int p = power(runs.getLast(), new int[] {i, j - i}, n); while (p <= runs.getLast()[2]) { - mergeTopmost2(a, runs); + mergeTopmost2(a, runs, c); } runs.add(new int[] {i, j - i, p}); @@ -158,7 +194,7 @@ public class IMPL_M_1 > { } while (runs.size() >= 2) { - mergeTopmost2(a, runs); + mergeTopmost2(a, runs, c); } } diff --git a/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_2.java b/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_2.java index a552fca..b892e84 100644 --- a/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_2.java +++ b/app/src/main/java/de/uni_marburg/powersort/MSort/IMPL_M_2.java @@ -79,7 +79,7 @@ public class IMPL_M_2{ * of the minimum stack length required as a function of the length * of the array being sorted and the minimum merge sequence length. */ - private static final int MIN_MERGE = 32; + private static final int MIN_MERGE = 24; /** * The array being sorted. diff --git a/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java b/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java index 5883b93..105f6a0 100644 --- a/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java +++ b/app/src/main/java/de/uni_marburg/powersort/sort/SortEnum.java @@ -2,6 +2,8 @@ package de.uni_marburg.powersort.sort; 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.benchmark.NaturalOrder; import de.uni_marburg.powersort.sort.dpqs.DualPivotQuicksort; @@ -10,6 +12,8 @@ public enum SortEnum { FASTER_FINN_SORT, ASORT, FINN_SORT, + IMPL_M_11, + IMPL_M_21, DPQS, QUICK_SORT, MERGE_SORT, @@ -23,6 +27,8 @@ public enum SortEnum { case MERGE_SORT -> array -> MergeSort.legacyMergeSort(array, NaturalOrder.INSTANCE); 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_11 -> array -> IMPL_M_1.powerSort(array,NaturalOrder.INSTANCE); + case IMPL_M_21 -> array -> IMPL_M_2.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); }; diff --git a/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortT.java b/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortT.java index 8a0bd76..feb81dc 100644 --- a/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortT.java +++ b/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortT.java @@ -33,22 +33,22 @@ public class PowerSortT { public static void testMerge() { List run1 = new ArrayList<>(Arrays.asList(1, 4, 6)); List run2 = new ArrayList<>(Arrays.asList(2, 3, 5)); - List result = merge(run1, run2); - System.out.println("Test merge: " + result); + // List result = merge(run1, run2); + // System.out.println("Test merge: " + result); } // Test for mergeInplace public static void testMergeInplace() { List A = new ArrayList<>(Arrays.asList(1, 4, 6, 2, 3, 5)); - mergeInplace(A, 0, 3, 6); + //mergeInplace(A, 0, 3, 6); System.out.println("Test mergeInplace: " + A); } // Test for extendRun public static void testExtendRun() { List A = new ArrayList<>(Arrays.asList(1, 2, 3, 6, 5, 4)); - int endIndex = extendRun(A, 0); - System.out.println("Test extendRun (from 0): " + endIndex); + // int endIndex = extendRun(A, 0); + // System.out.println("Test extendRun (from 0): " + endIndex); System.out.println("Modified List: " + A); } @@ -76,14 +76,14 @@ public class PowerSortT { List runs = new ArrayList<>(); runs.add(new int[]{0, 3, 1}); runs.add(new int[]{3, 3, 1}); - mergeTopmost2(A, runs); + // mergeTopmost2(A, runs); System.out.println("Test mergeTopmost2: " + A); } // Test for powerSort public static void testPowerSort() { List A = new ArrayList<>(Arrays.asList(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)); - powerSort(A); + // powerSort(A); System.out.println("Test powerSort: " + A); } } diff --git a/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortTest.java b/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortTest.java index 1d1bb78..07d5ab6 100644 --- a/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortTest.java +++ b/app/src/test/java/de/uni_marburg/powersort/MSort/PowerSortTest.java @@ -28,7 +28,7 @@ class PowerSortTest { fillWithAscRunsHighToLow(a, runs, 1); MERGE_COST = 0; System.out.println("Sorting with Powersort:"); - powerSort(a); + //powerSort(a); System.out.println("Merge cost: " + MERGE_COST); } @@ -36,7 +36,7 @@ class PowerSortTest { public void testWithFinnInputList() { List numbers = List.of(new Integer[] {24, 25, 26, 27, 28, 21, 22, 23, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 3, 1, 2}); - powerSort(numbers); + // powerSort(numbers); System.out.println("Result: "); System.out.println(new ArrayList<>(List.of(numbers)));