From 0b5c6df766b22fd547cde21a7f835e7eae21d213 Mon Sep 17 00:00:00 2001 From: Daniel Langbein Date: Sun, 8 Dec 2024 12:10:04 +0000 Subject: [PATCH] jdk sort intro & benchmark preparations --- .../powersort/benchmark/DummySort.java | 19 ++++++ .../powersort/benchmark/DummySort2.java | 23 +++++++ .../powersort/benchmark/Educational.java | 62 +++++++++++++++++++ .../uni_marburg/powersort/benchmark/Main.java | 30 +++++++++ .../powersort/benchmark/NaturalOrder.java | 15 +++++ .../powersort/benchmark/SomeComparable.java | 11 ++++ 6 files changed, 160 insertions(+) create mode 100644 app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort.java create mode 100644 app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort2.java create mode 100644 app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java create mode 100644 app/src/main/java/de/uni_marburg/powersort/benchmark/Main.java create mode 100644 app/src/main/java/de/uni_marburg/powersort/benchmark/NaturalOrder.java create mode 100644 app/src/main/java/de/uni_marburg/powersort/benchmark/SomeComparable.java diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort.java new file mode 100644 index 0000000..16e4c76 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort.java @@ -0,0 +1,19 @@ +package de.uni_marburg.powersort.benchmark; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Same class and method interface as JDK23 TimSort.java with its sort() method. + *

+ * Uses Arrays.sort() for sorting. + */ +class DummySort { + public static void sort(T[] a, int lo, int hi, Comparator c, + T[] work, int workBase, int workLen) { + assert lo == 0; + assert hi == a.length; + assert work == null; + Arrays.sort(a, c); + } +} diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort2.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort2.java new file mode 100644 index 0000000..96edd2d --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/DummySort2.java @@ -0,0 +1,23 @@ +package de.uni_marburg.powersort.benchmark; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Same class and method interface as TimSort.java with its sort() method. + *

+ * Uses Arrays.sort() for sorting. + * But calls it a.length times which makes this implementation really inefficient. + */ +class DummySort2 { + public static void sort(T[] a, int lo, int hi, Comparator c, + T[] work, int workBase, int workLen) { + assert lo == 0; + assert hi == a.length; + assert work == null; + + for (int i = 0; i < a.length; i++) { + Arrays.sort(a, c); + } + } +} diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java new file mode 100644 index 0000000..2f35045 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/Educational.java @@ -0,0 +1,62 @@ +package de.uni_marburg.powersort.benchmark; + +import java.util.Arrays; + +/** + * Quick intro on how sorting arrays works in JDK 23. + */ +public class Educational { + public static void main(String[] args) { + sortObjectsAvoidingComparableTimSort(); + sortObjects(); + sortPrimitives(); + } + + /** + * TODO: If this is no slower than sortObjects(), then we could avoid ComparableTimSort :) + *

+ * Quote from JDK23 ComparableTimSort.java + *

+ * If you are using an optimizing VM, you may find that ComparableTimSort + * offers no performance benefit over TimSort in conjunction with a + * comparator that simply returns {@code ((Comparable)first).compareTo(Second)}. + * If this is the case, you are better off deleting ComparableTimSort to + * eliminate the code duplication. + */ + private static void sortObjectsAvoidingComparableTimSort() { + SomeComparable[] a = { + new SomeComparable(1), + new SomeComparable(0) + }; + + NaturalOrder c = NaturalOrder.INSTANCE; + // -> TimSort.sort(a, 0, a.length, c, null, 0, 0); + // -> All elements in the array must implement the {@link Comparable} interface. + Arrays.sort(a, c); + + System.out.println(Arrays.toString(a)); + } + + public static void sortObjects() { + SomeComparable[] a = { + new SomeComparable(1), + new SomeComparable(0) + }; + + + // -> ComparableTimSort.sort(a, 0, a.length, null, 0, 0); + // -> All elements in the array must implement the {@link Comparable} interface. + Arrays.sort(a); + + System.out.println(Arrays.toString(a)); + } + + public static void sortPrimitives() { + int[] a = {1, 0}; + + // -> DualPivotQuicksort.sort(a, 0, 0, a.length); + Arrays.sort(a); + + System.out.println(Arrays.toString(a)); + } +} diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/Main.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/Main.java new file mode 100644 index 0000000..907d402 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/Main.java @@ -0,0 +1,30 @@ +package de.uni_marburg.powersort.benchmark; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Comparator; + +public class Main { + public static void main(final String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { + final SomeComparable[] a = { + new SomeComparable(1), + new SomeComparable(0) + }; + + final Method[] sortImplementations = getSortImplementations(); + + final NaturalOrder c = NaturalOrder.INSTANCE; + for (Method sortImplementation : sortImplementations) { + sortImplementation.invoke(null, a, 0, 0, c, null, 0, 0); + System.out.println(Arrays.toString(a)); + } + } + + static Method[] getSortImplementations() throws NoSuchMethodException { + return new Method[]{ + DummySort.class.getMethod("sort", Object[].class, int.class, int.class, Comparator.class, Object[].class, int.class, int.class), + DummySort2.class.getMethod("sort", Object[].class, int.class, int.class, Comparator.class, Object[].class, int.class, int.class) + }; + } +} diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/NaturalOrder.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/NaturalOrder.java new file mode 100644 index 0000000..e60074c --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/NaturalOrder.java @@ -0,0 +1,15 @@ +package de.uni_marburg.powersort.benchmark; + +import java.util.Comparator; + +/** + * Copied from JDK23 Arrays.java + */ +final class NaturalOrder implements Comparator { + @SuppressWarnings("unchecked") + public int compare(Object first, Object second) { + return ((Comparable) first).compareTo(second); + } + + static final NaturalOrder INSTANCE = new NaturalOrder(); +} diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/SomeComparable.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/SomeComparable.java new file mode 100644 index 0000000..85823ad --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/SomeComparable.java @@ -0,0 +1,11 @@ +package de.uni_marburg.powersort.benchmark; + +/** + * A class for tiny, comparable objects. + */ +record SomeComparable(int id) implements Comparable { + @Override + public int compareTo(SomeComparable other) { + return id - other.id; + } +}