mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-01-21 19:50:35 +01:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
fa70412791
@ -56,9 +56,3 @@ Run the task "test":
|
|||||||
```shell
|
```shell
|
||||||
./gradlew test
|
./gradlew test
|
||||||
```
|
```
|
||||||
|
|
||||||
## TimSort
|
|
||||||
|
|
||||||
Imported from
|
|
||||||
- src/java.base/share/classes/java/util/TimSort.java
|
|
||||||
- src/java.base/share/classes/java/util/ComparableTimSort.java
|
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
package de.uni_marburg.powersort.benchmark;
|
package de.uni_marburg.powersort;
|
||||||
|
|
||||||
|
import de.uni_marburg.powersort.benchmark.DummyComparable1;
|
||||||
|
import de.uni_marburg.powersort.benchmark.NaturalOrder;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
@ -3,7 +3,7 @@ package de.uni_marburg.powersort.benchmark;
|
|||||||
/**
|
/**
|
||||||
* A class for tiny, comparable objects.
|
* A class for tiny, comparable objects.
|
||||||
*/
|
*/
|
||||||
record DummyComparable1(int id) implements Comparable<DummyComparable1> {
|
public record DummyComparable1(int id) implements Comparable<DummyComparable1> {
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(DummyComparable1 other) {
|
public int compareTo(DummyComparable1 other) {
|
||||||
return id - other.id;
|
return id - other.id;
|
||||||
|
@ -3,11 +3,9 @@ package de.uni_marburg.powersort.data;
|
|||||||
import de.uni_marburg.powersort.benchmark.IntegerArray;
|
import de.uni_marburg.powersort.benchmark.IntegerArray;
|
||||||
import de.uni_marburg.powersort.benchmark.LongFormatter;
|
import de.uni_marburg.powersort.benchmark.LongFormatter;
|
||||||
|
|
||||||
import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_ASC;
|
|
||||||
|
|
||||||
public class AscendingIntegers extends IntegerSupplier {
|
public class AscendingIntegers extends IntegerSupplier {
|
||||||
public AscendingIntegers() {
|
public AscendingIntegers(int size) {
|
||||||
super(IntegerArray.ascending( 1, SIZE_ASC));
|
super(IntegerArray.ascending( 1, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package de.uni_marburg.powersort.data;
|
|
||||||
|
|
||||||
public interface DataArraySizes {
|
|
||||||
int SIZE_RAND = 50_000_000;
|
|
||||||
int SIZE_ASC = 50_000_000;
|
|
||||||
int SIZE_DESC = 50_000_000;
|
|
||||||
}
|
|
@ -4,18 +4,23 @@ public enum DataEnum {
|
|||||||
RANDOM_INTEGERS,
|
RANDOM_INTEGERS,
|
||||||
ASCENDING_INTEGERS,
|
ASCENDING_INTEGERS,
|
||||||
DESCENDING_INTEGERS,
|
DESCENDING_INTEGERS,
|
||||||
ASCENDING_RUNS;
|
ASCENDING_RUNS,
|
||||||
|
ASCENDING_RUNS_WITH_OVERLAP;
|
||||||
|
|
||||||
public ObjectSupplier get() {
|
public ObjectSupplier get() {
|
||||||
// We use a seed to get the same random list every time -> Repeatable benchmarks on same input data!
|
// We use a seed to get the same random list every time -> Repeatable benchmarks on same input data!
|
||||||
// final long seed = 3651660232967549736L; // System.nanoTime() ++ Math.random()
|
// final long seed = 3651660232967549736L; // System.nanoTime() ++ Math.random()
|
||||||
final long seed = 140506881906827520L; // (long) 'P' * (long) 'O' *(long) 'W' * (long) 'E' * (long) 'R' * (long) 'S' * (long) 'O' * (long) 'R' * (long) 'T';
|
final long seed = 140506881906827520L; // (long) 'P' * (long) 'O' *(long) 'W' * (long) 'E' * (long) 'R' * (long) 'S' * (long) 'O' * (long) 'R' * (long) 'T';
|
||||||
|
|
||||||
|
int longListSize = 50_000_000;
|
||||||
|
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
case RANDOM_INTEGERS -> new RandomIntegers(seed);
|
case RANDOM_INTEGERS -> new RandomIntegers(longListSize, seed);
|
||||||
case ASCENDING_INTEGERS -> new AscendingIntegers();
|
case ASCENDING_INTEGERS -> new AscendingIntegers(longListSize);
|
||||||
case DESCENDING_INTEGERS -> new DescendingIntegers();
|
case DESCENDING_INTEGERS -> new DescendingIntegers(longListSize);
|
||||||
case ASCENDING_RUNS -> AscendingRuns.newAscendingRuns(10000, 10000, -10000);
|
|
||||||
|
case ASCENDING_RUNS -> AscendingRuns.newAscendingRuns(10_000, 10_000, -10_000);
|
||||||
|
case ASCENDING_RUNS_WITH_OVERLAP -> AscendingRuns.newAscendingRuns(10_000, 10_000, -5_000);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,9 @@ package de.uni_marburg.powersort.data;
|
|||||||
import de.uni_marburg.powersort.benchmark.IntegerArray;
|
import de.uni_marburg.powersort.benchmark.IntegerArray;
|
||||||
import de.uni_marburg.powersort.benchmark.LongFormatter;
|
import de.uni_marburg.powersort.benchmark.LongFormatter;
|
||||||
|
|
||||||
import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_DESC;
|
|
||||||
|
|
||||||
public class DescendingIntegers extends IntegerSupplier {
|
public class DescendingIntegers extends IntegerSupplier {
|
||||||
public DescendingIntegers() {
|
public DescendingIntegers(int size) {
|
||||||
super(IntegerArray.descending(SIZE_DESC, 1));
|
super(IntegerArray.descending(size, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,11 +3,9 @@ package de.uni_marburg.powersort.data;
|
|||||||
import de.uni_marburg.powersort.benchmark.IntegerArray;
|
import de.uni_marburg.powersort.benchmark.IntegerArray;
|
||||||
import de.uni_marburg.powersort.benchmark.LongFormatter;
|
import de.uni_marburg.powersort.benchmark.LongFormatter;
|
||||||
|
|
||||||
import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_RAND;
|
|
||||||
|
|
||||||
public class RandomIntegers extends IntegerSupplier {
|
public class RandomIntegers extends IntegerSupplier {
|
||||||
public RandomIntegers(final long seed) {
|
public RandomIntegers(final int size, final long seed) {
|
||||||
super(IntegerArray.random(SIZE_RAND, seed));
|
super(IntegerArray.random(size, seed));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Imported from OpenJDK git repo ComparableTimSort.java
|
||||||
|
*/
|
||||||
|
|
||||||
package de.uni_marburg.powersort.sort;
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
package de.uni_marburg.powersort.sort;
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
|
import de.uni_marburg.powersort.FinnSort.FinnSort;
|
||||||
import de.uni_marburg.powersort.benchmark.NaturalOrder;
|
import de.uni_marburg.powersort.benchmark.NaturalOrder;
|
||||||
|
|
||||||
public enum SortEnum {
|
public enum SortEnum {
|
||||||
// BUBBLE_SORT,
|
// BUBBLE_SORT,
|
||||||
MERGE_SORT,
|
MERGE_SORT,
|
||||||
TIM_SORT;
|
TIM_SORT,
|
||||||
|
FIN_SORT,
|
||||||
|
ASORT;
|
||||||
|
|
||||||
public SimpleSort get() {
|
public SimpleSort get() {
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
// case BUBBLE_SORT -> array -> BubbleSort.sort(array, NaturalOrder.INSTANCE);
|
// case BUBBLE_SORT -> array -> BubbleSort.sort(array, NaturalOrder.INSTANCE);
|
||||||
case MERGE_SORT -> array -> MergeSort.legacyMergeSort(array, NaturalOrder.INSTANCE);
|
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 TIM_SORT -> array -> TimSort.sort(array, 0, array.length, NaturalOrder.INSTANCE, null, 0, 0);
|
||||||
|
case FIN_SORT -> array -> FinnSort.sort(array, NaturalOrder.INSTANCE);
|
||||||
|
case ASORT -> array -> ASort.sort(array, NaturalOrder.INSTANCE);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Imported from OpenJDK git repo TimSort.java
|
||||||
|
*/
|
||||||
|
|
||||||
package de.uni_marburg.powersort.sort;
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
41
app/src/test/java/de/uni_marburg/powersort/JUnitUtil.java
Normal file
41
app/src/test/java/de/uni_marburg/powersort/JUnitUtil.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package de.uni_marburg.powersort;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.converter.SimpleArgumentConverter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class JUnitUtil {
|
||||||
|
/**
|
||||||
|
* https://stackoverflow.com/a/46850299/6334421
|
||||||
|
*/
|
||||||
|
public static class IntArrayConverter extends SimpleArgumentConverter {
|
||||||
|
@Override
|
||||||
|
protected int[] convert(Object source, Class<?> targetType) {
|
||||||
|
if (source instanceof String s && int[].class.isAssignableFrom(targetType)) {
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
String[] strings = s.split("\\s*\\|\\s*");
|
||||||
|
return Arrays.stream(strings).mapToInt(Integer::valueOf).toArray();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Conversion from " + source.getClass()
|
||||||
|
+ " to " + targetType + " not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class IntegerArrayConverter extends SimpleArgumentConverter {
|
||||||
|
@Override
|
||||||
|
protected Integer[] convert(Object source, Class<?> targetType) {
|
||||||
|
if (source instanceof String s && Integer[].class.isAssignableFrom(targetType)) {
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
return new Integer[0];
|
||||||
|
}
|
||||||
|
String[] strings = s.split("\\s*\\|\\s*");
|
||||||
|
return Arrays.stream(strings).map(Integer::valueOf).toArray(Integer[]::new);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Conversion from " + source.getClass()
|
||||||
|
+ " to " + targetType + " not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package de.uni_marburg.powersort.data;
|
package de.uni_marburg.powersort.data;
|
||||||
|
|
||||||
|
import de.uni_marburg.powersort.JUnitUtil;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.converter.ConvertWith;
|
import org.junit.jupiter.params.converter.ConvertWith;
|
||||||
import org.junit.jupiter.params.converter.SimpleArgumentConverter;
|
|
||||||
import org.junit.jupiter.params.provider.CsvSource;
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -10,26 +10,6 @@ import java.util.Arrays;
|
|||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class AscendingRunsTest {
|
class AscendingRunsTest {
|
||||||
/**
|
|
||||||
* https://stackoverflow.com/a/46850299/6334421
|
|
||||||
*/
|
|
||||||
private static class IntArrayConverter extends SimpleArgumentConverter {
|
|
||||||
@Override
|
|
||||||
protected Object convert(Object source, Class<?> targetType) {
|
|
||||||
if (source instanceof String s && int[].class.isAssignableFrom(targetType)) {
|
|
||||||
if (s.isEmpty()) {
|
|
||||||
return new int[0];
|
|
||||||
}
|
|
||||||
String[] strings = s.split("\\s*\\|\\s*");
|
|
||||||
return Arrays.stream(strings).mapToInt(Integer::valueOf).toArray();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Conversion from " + source.getClass()
|
|
||||||
+ " to " + targetType + " not supported.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@CsvSource({
|
@CsvSource({
|
||||||
"0,1,-1,''",
|
"0,1,-1,''",
|
||||||
@ -38,7 +18,7 @@ class AscendingRunsTest {
|
|||||||
"2,2,-2,0|1|-2|-1",
|
"2,2,-2,0|1|-2|-1",
|
||||||
"2,4,-2,0|1|2|3|-2|-1|0|1",
|
"2,4,-2,0|1|2|3|-2|-1|0|1",
|
||||||
})
|
})
|
||||||
void testAscendingRuns1(int numOfRuns, int runLength, int decreaseBetweenRuns, @ConvertWith(IntArrayConverter.class) int[] expected) {
|
void testAscendingRuns1(int numOfRuns, int runLength, int decreaseBetweenRuns, @ConvertWith(JUnitUtil.IntArrayConverter.class) int[] expected) {
|
||||||
Integer[] actualIntegers = AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns).getCopy();
|
Integer[] actualIntegers = AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns).getCopy();
|
||||||
int[] actual = Arrays.stream(actualIntegers).mapToInt(Integer::valueOf).toArray();
|
int[] actual = Arrays.stream(actualIntegers).mapToInt(Integer::valueOf).toArray();
|
||||||
assertArrayEquals(expected, actual);
|
assertArrayEquals(expected, actual);
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
|
public class ASortTest extends AbstractSortTest {
|
||||||
|
ASortTest() {
|
||||||
|
sortAlg = SortEnum.ASORT;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
|
import de.uni_marburg.powersort.JUnitUtil;
|
||||||
|
import de.uni_marburg.powersort.data.AscendingRuns;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.converter.ConvertWith;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
|
|
||||||
|
public abstract class AbstractSortTest {
|
||||||
|
SortEnum sortAlg;
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"''",
|
||||||
|
"1337",
|
||||||
|
"3|2|1",
|
||||||
|
"1|1",
|
||||||
|
"2|1",
|
||||||
|
"2|1|2",
|
||||||
|
})
|
||||||
|
void test1(@ConvertWith(JUnitUtil.IntegerArrayConverter.class) Integer[] array) {
|
||||||
|
sortAndCheckResult(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"3,7,-13",
|
||||||
|
"3,7,-3",
|
||||||
|
})
|
||||||
|
void test2(int numOfRuns, int runLength, int decreaseBetweenRuns) {
|
||||||
|
Integer[] array = AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns).getCopy();
|
||||||
|
sortAndCheckResult(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sortAndCheckResult(Integer[] array){
|
||||||
|
Integer[] expected = Arrays.copyOf(array, array.length);
|
||||||
|
Arrays.sort(expected);
|
||||||
|
|
||||||
|
sortAlg.get().sort(array);
|
||||||
|
assertArrayEquals(expected, array);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
|
public class FinnSortTest extends AbstractSortTest {
|
||||||
|
FinnSortTest() {
|
||||||
|
sortAlg = SortEnum.FIN_SORT;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user