mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-01-21 19:50:35 +01:00
benchmark: JMH experiments
This commit is contained in:
parent
9a99716a0a
commit
dbe83ac3cb
@ -0,0 +1,47 @@
|
|||||||
|
package de.uni_marburg.powersort.benchmark;
|
||||||
|
|
||||||
|
import de.uni_marburg.powersort.TimSort;
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
// TODO: The parameters are way too low. Use for debugging only!
|
||||||
|
@Fork(0)
|
||||||
|
@Warmup(iterations = 0)
|
||||||
|
@Measurement(iterations = 3)
|
||||||
|
public class BenchmarkJmh {
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public static class State1 {
|
||||||
|
Integer[] readOnly = IntegerArray.random(500_000);;
|
||||||
|
Integer[] a;
|
||||||
|
|
||||||
|
@Setup(Level.Invocation)
|
||||||
|
public void setup() {
|
||||||
|
a = Arrays.copyOf(readOnly, readOnly.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
@Benchmark
|
||||||
|
public void rand1DummySort(State1 s, Blackhole bh) {
|
||||||
|
DummySort.sort(s.a, 0, s.a.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
@Benchmark
|
||||||
|
public void rand1TimSort(State1 s, Blackhole bh) {
|
||||||
|
TimSort.sort(s.a, 0, s.a.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||||
|
bh.consume(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
@Benchmark
|
||||||
|
public void rand1MergeSort(State1 s) {
|
||||||
|
MergeSort.legacyMergeSort(s.a, NaturalOrder.INSTANCE);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package de.uni_marburg.powersort.benchmark;
|
||||||
|
|
||||||
|
public class IntegerArray {
|
||||||
|
private IntegerArray() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer[] random(final int length) {
|
||||||
|
return random(length, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer[] random(final int length, final int minInt, final int maxInt) {
|
||||||
|
final Integer[] list = new Integer[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
list[i] = RandomInt.integer(minInt, maxInt);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,9 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom benchmark.
|
||||||
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
final SortImpl[] sortImplementations = getSortImplementations();
|
final SortImpl[] sortImplementations = getSortImplementations();
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
package de.uni_marburg.powersort.benchmark;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copied from JDK23 Arrays.java
|
||||||
|
*/
|
||||||
|
public class MergeSort {
|
||||||
|
/**
|
||||||
|
* Tuning parameter: list size at or below which insertion sort will be
|
||||||
|
* used in preference to mergesort.
|
||||||
|
* To be removed in a future release.
|
||||||
|
*/
|
||||||
|
private static final int INSERTIONSORT_THRESHOLD = 7;
|
||||||
|
|
||||||
|
/** To be removed in a future release. */
|
||||||
|
public static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
|
||||||
|
T[] aux = a.clone();
|
||||||
|
mergeSort(aux, a, 0, a.length, 0, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Src is the source array that starts at index 0
|
||||||
|
* Dest is the (possibly larger) array destination with a possible offset
|
||||||
|
* low is the index in dest to start sorting
|
||||||
|
* high is the end index in dest to end sorting
|
||||||
|
* off is the offset into src corresponding to low in dest
|
||||||
|
* To be removed in a future release.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
private static void mergeSort(Object[] src,
|
||||||
|
Object[] dest,
|
||||||
|
int low, int high, int off,
|
||||||
|
Comparator c) {
|
||||||
|
int length = high - low;
|
||||||
|
|
||||||
|
// Insertion sort on smallest arrays
|
||||||
|
if (length < INSERTIONSORT_THRESHOLD) {
|
||||||
|
for (int i=low; i<high; i++)
|
||||||
|
for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
|
||||||
|
swap(dest, j, j-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively sort halves of dest into src
|
||||||
|
int destLow = low;
|
||||||
|
int destHigh = high;
|
||||||
|
low += off;
|
||||||
|
high += off;
|
||||||
|
int mid = (low + high) >>> 1;
|
||||||
|
mergeSort(dest, src, low, mid, -off, c);
|
||||||
|
mergeSort(dest, src, mid, high, -off, c);
|
||||||
|
|
||||||
|
// If list is already sorted, just copy from src to dest. This is an
|
||||||
|
// optimization that results in faster sorts for nearly ordered lists.
|
||||||
|
if (c.compare(src[mid-1], src[mid]) <= 0) {
|
||||||
|
System.arraycopy(src, low, dest, destLow, length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge sorted halves (now in src) into dest
|
||||||
|
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
|
||||||
|
if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
|
||||||
|
dest[i] = src[p++];
|
||||||
|
else
|
||||||
|
dest[i] = src[q++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps x[a] with x[b].
|
||||||
|
*/
|
||||||
|
private static void swap(Object[] x, int a, int b) {
|
||||||
|
Object t = x[a];
|
||||||
|
x[a] = x[b];
|
||||||
|
x[b] = t;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package de.uni_marburg.powersort.benchmark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides utility methods related to random integers.
|
||||||
|
*/
|
||||||
|
public final class RandomInt {
|
||||||
|
private RandomInt() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random integer.
|
||||||
|
*
|
||||||
|
* @return A random integer.
|
||||||
|
*/
|
||||||
|
public static int integer() {
|
||||||
|
return integer(Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
public static int integer(final int minInt, final int maxInt) {
|
||||||
|
final double random = Math.random() * (maxInt - minInt) - minInt;
|
||||||
|
return (int) Math.round(random);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package de.uni_marburg.powersort.benchmark;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class RandomIntTest {
|
||||||
|
protected RandomIntTest(){
|
||||||
|
// This constructor is intentionally empty. Nothing special is needed here.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRandomInt() {
|
||||||
|
final double accuracy = 0.99;
|
||||||
|
final int min = (int) Math.round(Integer.MIN_VALUE * accuracy);
|
||||||
|
final int max = (int) Math.round(Integer.MAX_VALUE * accuracy);
|
||||||
|
|
||||||
|
boolean minPassed = false;
|
||||||
|
boolean maxPassed = false;
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
final int random = RandomInt.integer();
|
||||||
|
System.out.println(random); //NOPMD - suppressed SystemPrintln - Testing
|
||||||
|
|
||||||
|
if (random <= min) {
|
||||||
|
minPassed = true;
|
||||||
|
}
|
||||||
|
if (random >= max) {
|
||||||
|
maxPassed = true;
|
||||||
|
}
|
||||||
|
if (minPassed && maxPassed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.fail("min or max not reached - not a random int generator");
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user