From 904d462fc681b09098e99aeee46a94f9e2f176e7 Mon Sep 17 00:00:00 2001 From: Daniel Langbein Date: Wed, 11 Dec 2024 17:08:01 +0000 Subject: [PATCH] benchmark: @Param & DataEnum --- .../benchmark/AbstractBenchmark.java | 32 ++++++++++++++--- .../benchmark/DummySortBenchmark.java | 2 +- .../benchmark/MergeSortBenchmark.java | 2 +- .../powersort/benchmark/IntegerArray.java | 30 ++++++++++++---- .../uni_marburg/powersort/benchmark/Main.java | 34 ++++++++----------- .../powersort/data/AscendingIntegers.java | 17 ++++++++++ .../uni_marburg/powersort/data/DataEnum.java | 15 ++++++++ .../powersort/data/ObjectSupplier.java | 2 +- 8 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java create mode 100644 app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java diff --git a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/AbstractBenchmark.java b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/AbstractBenchmark.java index 8603207..2be81c0 100644 --- a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/AbstractBenchmark.java +++ b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/AbstractBenchmark.java @@ -1,7 +1,19 @@ package de.uni_marburg.powersort.benchmark; -import de.uni_marburg.powersort.data.RandomIntegers; -import org.openjdk.jmh.annotations.*; +import de.uni_marburg.powersort.data.DataEnum; +import de.uni_marburg.powersort.data.ObjectSupplier; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -22,13 +34,23 @@ import java.util.concurrent.TimeUnit; */ @State(Scope.Benchmark) public abstract class AbstractBenchmark { - private final RandomIntegers readonly = new RandomIntegers(); - /* package-protected */ Integer[] array; + @Param() + private DataEnum dataEnum; + + private DataEnum prevDataEnum = null; + private ObjectSupplier data; + + /* package-protected */ Object[] workingCopy; // TODO: This is inaccurate. How to create and use separate arrays for each warmup x iteration x sortAlgorithm ? @Setup(Level.Invocation) public void setup() { - array = readonly.getCopy(); + if (dataEnum != prevDataEnum){ + System.out.println(prevDataEnum + " => " + dataEnum); + prevDataEnum = dataEnum; + data = dataEnum.get(); + } + workingCopy = data.getCopy(); } @Benchmark diff --git a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/DummySortBenchmark.java b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/DummySortBenchmark.java index 3bb2bf9..2091b60 100644 --- a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/DummySortBenchmark.java +++ b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/DummySortBenchmark.java @@ -5,6 +5,6 @@ import de.uni_marburg.powersort.sort.DummySort; public class DummySortBenchmark extends AbstractBenchmark { @Override public void sort() { - DummySort.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0); + DummySort.sort(workingCopy, 0, workingCopy.length, NaturalOrder.INSTANCE, null, 0, 0); } } diff --git a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/MergeSortBenchmark.java b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/MergeSortBenchmark.java index 75e4eb6..f125585 100644 --- a/app/src/jmh/java/de/uni_marburg/powersort/benchmark/MergeSortBenchmark.java +++ b/app/src/jmh/java/de/uni_marburg/powersort/benchmark/MergeSortBenchmark.java @@ -5,6 +5,6 @@ import de.uni_marburg.powersort.sort.MergeSort; public class MergeSortBenchmark extends AbstractBenchmark { @Override public void sort() { - MergeSort.legacyMergeSort(array, NaturalOrder.INSTANCE); + MergeSort.legacyMergeSort(workingCopy, NaturalOrder.INSTANCE); } } diff --git a/app/src/main/java/de/uni_marburg/powersort/benchmark/IntegerArray.java b/app/src/main/java/de/uni_marburg/powersort/benchmark/IntegerArray.java index 911edc1..13a449d 100644 --- a/app/src/main/java/de/uni_marburg/powersort/benchmark/IntegerArray.java +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/IntegerArray.java @@ -17,19 +17,35 @@ public class IntegerArray { } /** - * @return [start, start-1, ..., end+1, end] + * @return [high, high-1, ..., low+1, low] */ - public static Integer[] descending(final int start, final int end) { - assert start > end; + public static Integer[] descending(final int high, final int low) { + assert high > low; - Integer[] list = new Integer[start - end + 1]; + Integer[] list = new Integer[high - low + 1]; for (int i = 0; i < list.length; i++) { - int value = start - i; + int value = high - i; list[i] = value; } - assert list[0] == start; - assert list[list.length - 1] == end; + assert list[0] == high; + assert list[list.length - 1] == low; + return list; + } + /** + * @return [low, low-1, ..., high+1, high] + */ + public static Integer[] ascending(final int low, final int high) { + assert low < high; + + Integer[] list = new Integer[low - high + 1]; + for (int i = 0; i < list.length; i++) { + int value = low + i; + list[i] = value; + } + + assert list[0] == low; + assert list[list.length - 1] == high; return list; } } 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 index 59d8848..4c8a996 100644 --- a/app/src/main/java/de/uni_marburg/powersort/benchmark/Main.java +++ b/app/src/main/java/de/uni_marburg/powersort/benchmark/Main.java @@ -1,16 +1,13 @@ package de.uni_marburg.powersort.benchmark; +import de.uni_marburg.powersort.data.DataEnum; import de.uni_marburg.powersort.sort.DummySort; import de.uni_marburg.powersort.sort.MergeSort; import de.uni_marburg.powersort.sort.TimSort; -import de.uni_marburg.powersort.data.DescendingIntegers; -import de.uni_marburg.powersort.data.RandomIntegers; import de.uni_marburg.powersort.data.ObjectSupplier; -import java.util.Arrays; -import java.util.List; +import java.util.EnumSet; import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; /** * Custom benchmark. @@ -18,10 +15,10 @@ import java.util.function.Supplier; public class Main { public static void main(final String[] args) { final SortImpl[] sortImplementations = getSortImplementations(); - final List> sortInputSuppliers = getSortInputSuppliers(); + final EnumSet dataEnums = getSortInputSuppliers(); - for (Supplier sortInputSupplier : sortInputSuppliers) { - ObjectSupplier objectSupplier = sortInputSupplier.get(); + for (DataEnum dataEnum : dataEnums) { + ObjectSupplier objectSupplier = dataEnum.get(); System.out.println("\n" + objectSupplier.title()); for (SortImpl sortImplementation : sortImplementations) { @@ -53,6 +50,12 @@ public class Main { TimSort.sort(a, 0, a.length, NaturalOrder.INSTANCE, null, 0, 0); } }, +// new SortImpl("FinnSort") { +// @Override +// public void sort(Object[] a) { +// FinnSort.sort(a); +// } +// }, new SortImpl("MergeSort") { @Override public void sort(Object[] a) { @@ -63,18 +66,11 @@ public class Main { } /** - * The returned ObjectSupplier objects are wrapped by Supplier objects. - * This way they are lazily created on their first access. + * The returned ObjectSupplier objects are wrapped by DataEnum objects. + * This way they are lazily created on their first access with DataEnum.get(). * This saves memory if we work with large lists. */ - static List> getSortInputSuppliers() { - return Arrays.asList( - // Three different random lists. - RandomIntegers::new, - RandomIntegers::new, - RandomIntegers::new, - // One descending list. - DescendingIntegers::new - ); + static EnumSet getSortInputSuppliers() { + return EnumSet.allOf(DataEnum.class); } } diff --git a/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java b/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java new file mode 100644 index 0000000..11e44b3 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/data/AscendingIntegers.java @@ -0,0 +1,17 @@ +package de.uni_marburg.powersort.data; + +import de.uni_marburg.powersort.benchmark.IntegerArray; +import de.uni_marburg.powersort.benchmark.LongFormatter; + +public class AscendingIntegers extends IntegerSupplier { + private static final int SIZE = 50_000_000; + + public AscendingIntegers() { + super(IntegerArray.ascending(SIZE, 0)); + } + + @Override + public String title() { + return "Array of " + LongFormatter.formatUnderscore(SIZE) + " ascending Integer objects."; + } +} diff --git a/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java b/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java new file mode 100644 index 0000000..6b8bd30 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/data/DataEnum.java @@ -0,0 +1,15 @@ +package de.uni_marburg.powersort.data; + +public enum DataEnum { + RANDOM_INTEGERS, + ASCENDING_INTEGERS, + DESCENDING_INTEGERS; + + public ObjectSupplier get() { + return switch (this) { + case RANDOM_INTEGERS -> new RandomIntegers(); + case ASCENDING_INTEGERS -> new AscendingIntegers(); + case DESCENDING_INTEGERS -> new DescendingIntegers(); + }; + } +} diff --git a/app/src/main/java/de/uni_marburg/powersort/data/ObjectSupplier.java b/app/src/main/java/de/uni_marburg/powersort/data/ObjectSupplier.java index f191abc..c1decbc 100644 --- a/app/src/main/java/de/uni_marburg/powersort/data/ObjectSupplier.java +++ b/app/src/main/java/de/uni_marburg/powersort/data/ObjectSupplier.java @@ -3,7 +3,7 @@ package de.uni_marburg.powersort.data; import java.util.Arrays; public abstract class ObjectSupplier { - final Object[] readOnly; + private final Object[] readOnly; ObjectSupplier(Object[] readOnly) { this.readOnly = readOnly;