benchmark: ascending runs

This commit is contained in:
Daniel Langbein 2024-12-15 20:07:28 +00:00
parent 025193595c
commit a262272b19
Signed by: langfingaz
GPG Key ID: 6C47C753F0823002
5 changed files with 102 additions and 5 deletions

View File

@ -16,7 +16,7 @@ public class IntegerArray {
* @return [high, high-1, ..., low+1, low] * @return [high, high-1, ..., low+1, low]
*/ */
public static Integer[] descending(final int high, final int low) { public static Integer[] descending(final int high, final int low) {
assert high > low; assert high >= low;
Integer[] list = new Integer[high - low + 1]; Integer[] list = new Integer[high - low + 1];
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
@ -32,9 +32,9 @@ public class IntegerArray {
* @return [low, low-1, ..., high+1, high] * @return [low, low-1, ..., high+1, high]
*/ */
public static Integer[] ascending(final int low, final int high) { public static Integer[] ascending(final int low, final int high) {
assert low < high; assert low <= high;
Integer[] list = new Integer[low - high + 1]; Integer[] list = new Integer[high - low + 1];
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
int value = low + i; int value = low + i;
list[i] = value; list[i] = value;

View File

@ -7,7 +7,7 @@ import static de.uni_marburg.powersort.data.DataArraySizes.SIZE_ASC;
public class AscendingIntegers extends IntegerSupplier { public class AscendingIntegers extends IntegerSupplier {
public AscendingIntegers() { public AscendingIntegers() {
super(IntegerArray.ascending(SIZE_ASC, 1)); super(IntegerArray.ascending( 1, SIZE_ASC));
} }
@Override @Override

View File

@ -0,0 +1,40 @@
package de.uni_marburg.powersort.data;
import de.uni_marburg.powersort.benchmark.IntegerArray;
public class AscendingRuns extends IntegerSupplier {
/**
* Can be used e.g. to construct this array:
* [0, 1, 2, 3, -2, -1, 0, 1, -4, -3, -2, -1]
*
* @param runLength >= 1
*/
public static AscendingRuns newAscendingRuns(
int numOfRuns,
int runLength,
int decreaseBetweenRuns
) {
if(numOfRuns < 0 || runLength <= 0){
throw new IllegalArgumentException();
}
Integer[] data = new Integer[numOfRuns * runLength];
for (int i = 0; i < numOfRuns; i++) {
int low = decreaseBetweenRuns * i;
int high = low + runLength - 1;
Integer[] run = IntegerArray.ascending(low, high);
System.arraycopy(run, 0, data, i * runLength, run.length);
}
return new AscendingRuns(data);
}
private AscendingRuns(Integer[] readonly) {
super(readonly);
}
@Override
public String title() {
return "Array of Integer objects with ascending runs";
}
}

View File

@ -3,7 +3,8 @@ package de.uni_marburg.powersort.data;
public enum DataEnum { public enum DataEnum {
RANDOM_INTEGERS, RANDOM_INTEGERS,
ASCENDING_INTEGERS, ASCENDING_INTEGERS,
DESCENDING_INTEGERS; DESCENDING_INTEGERS,
ASCENDING_RUNS;
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!
@ -14,6 +15,7 @@ public enum DataEnum {
case RANDOM_INTEGERS -> new RandomIntegers(seed); case RANDOM_INTEGERS -> new RandomIntegers(seed);
case ASCENDING_INTEGERS -> new AscendingIntegers(); case ASCENDING_INTEGERS -> new AscendingIntegers();
case DESCENDING_INTEGERS -> new DescendingIntegers(); case DESCENDING_INTEGERS -> new DescendingIntegers();
case ASCENDING_RUNS -> AscendingRuns.newAscendingRuns(10000, 10000, -10000);
}; };
} }
} }

View File

@ -0,0 +1,55 @@
package de.uni_marburg.powersort.data;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.converter.ConvertWith;
import org.junit.jupiter.params.converter.SimpleArgumentConverter;
import org.junit.jupiter.params.provider.CsvSource;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.*;
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
@CsvSource({
"0,1,-1,''",
"1,1,-1,0",
"1,2,-2,0|1",
"2,2,-2,0|1|-2|-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) {
Integer[] actualIntegers = AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns).getCopy();
int[] actual = Arrays.stream(actualIntegers).mapToInt(Integer::valueOf).toArray();
assertArrayEquals(expected, actual);
}
@ParameterizedTest
@CsvSource({
"1,0,-1",
"-1,1,-1",
})
void testAscendingRuns2(int numOfRuns, int runLength, int decreaseBetweenRuns) {
assertThrows(IllegalArgumentException.class, () -> AscendingRuns.newAscendingRuns(numOfRuns, runLength, decreaseBetweenRuns));
}
}