Skip to content

Commit 664d282

Browse files
committed
Optimized ShrinkingDistance.forCollection(..)
Working towards #435 effects
1 parent 19ae50e commit 664d282

File tree

3 files changed

+26
-21
lines changed

3 files changed

+26
-21
lines changed

api/src/main/java/net/jqwik/api/ShrinkingDistance.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@ public static ShrinkingDistance of(long... distances) {
2828

2929
@API(status = MAINTAINED, since = "1.0")
3030
public static <T> ShrinkingDistance forCollection(Collection<Shrinkable<T>> elements) {
31-
ShrinkingDistance sumDistanceOfElements = elements
32-
.stream()
33-
.map(Shrinkable::distance)
34-
.reduce(ShrinkingDistance.MIN, ShrinkingDistance::plus);
35-
31+
// This is an optimization to avoid creating temporary arrays, which the old streams-based implementation did.
32+
long[] collectedDistances = sumUp(toDistances(elements));
33+
ShrinkingDistance sumDistanceOfElements = new ShrinkingDistance(collectedDistances);
3634
return ShrinkingDistance.of(elements.size()).append(sumDistanceOfElements);
3735
}
3836

@@ -41,9 +39,9 @@ public static <T> ShrinkingDistance combine(List<Shrinkable<T>> shrinkables) {
4139
if (shrinkables.isEmpty()) {
4240
throw new IllegalArgumentException("At least one shrinkable is required");
4341
}
44-
// This is an optimization to avoid creating many temporary arrays, which the old streams-based implementation did.
45-
List<long[]> shrinkableDistances = toDistances(shrinkables);
46-
long[] combinedDistances = concatenate(shrinkableDistances);
42+
43+
// This is an optimization to avoid creating temporary arrays, which the old streams-based implementation did.
44+
long[] combinedDistances = concatenate(toDistances(shrinkables));
4745
return new ShrinkingDistance(combinedDistances);
4846
}
4947

@@ -52,7 +50,7 @@ private ShrinkingDistance(long[] distances) {
5250
}
5351

5452
@Override
55-
public boolean equals(Object o) {
53+
public boolean equals(@Nullable Object o) {
5654
if (this == o) return true;
5755
if (o == null || getClass() != o.getClass()) return false;
5856

@@ -109,7 +107,7 @@ private int compareDimension(ShrinkingDistance other, int i) {
109107

110108
@API(status = INTERNAL)
111109
public ShrinkingDistance plus(ShrinkingDistance other) {
112-
long[] summedUpDistances = sumUp(distances, other.distances);
110+
long[] summedUpDistances = sumUp(Arrays.asList(distances, other.distances));
113111
return new ShrinkingDistance(summedUpDistances);
114112
}
115113

@@ -120,7 +118,7 @@ public ShrinkingDistance append(ShrinkingDistance other) {
120118
}
121119

122120
@NotNull
123-
private static <T> List<long[]> toDistances(List<Shrinkable<T>> shrinkables) {
121+
private static <T> List<long[]> toDistances(Collection<Shrinkable<T>> shrinkables) {
124122
List<long[]> listOfDistances = new ArrayList<>(shrinkables.size());
125123
for (Shrinkable<?> tShrinkable : shrinkables) {
126124
long[] longs = tShrinkable.distance().distances;

api/src/main/java/net/jqwik/api/support/LongArraysSupport.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@ public static long at(long[] array, int i) {
1313
return array.length > i ? array[i] : 0;
1414
}
1515

16-
public static long[] sumUp(long[] left, long[] right) {
17-
long[] sum = new long[Math.max(left.length, right.length)];
18-
for (int i = 0; i < sum.length; i++) {
19-
long summedValue = at(left, i) + at(right, i);
20-
if (summedValue < 0) {
21-
summedValue = Long.MAX_VALUE;
16+
public static long[] sumUp(List<long[]> listOfArrays) {
17+
int maxDistanceSize = listOfArrays.stream().mapToInt(s -> s.length).max().orElse(0);
18+
long[] summedUpArray = new long[maxDistanceSize];
19+
Arrays.fill(summedUpArray, 0);
20+
for (long[] array : listOfArrays) {
21+
for (int i = 0; i < summedUpArray.length; i++) {
22+
summedUpArray[i] = plusWithoutOverflowAt(summedUpArray, array, i);
2223
}
23-
sum[i] = summedValue;
2424
}
25-
return sum;
25+
return summedUpArray;
26+
}
27+
28+
private static long plusWithoutOverflowAt(long[] left, long[] right, int index) {
29+
long summedValue = at(right, index) + at(left, index);
30+
if (summedValue < 0) {
31+
return Long.MAX_VALUE;
32+
}
33+
return summedValue;
2634
}
2735

2836
public static long[] concatenate(List<long[]> listOfArrays) {

engine/src/test/java/net/jqwik/engine/properties/shrinking/ShrinkingDistanceTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ class ForCollections {
8888
@Example
8989
void emptyCollection() {
9090
ShrinkingDistance distance = ShrinkingDistance.forCollection(Collections.emptyList());
91-
assertThat(distance).isEqualTo(ShrinkingDistance.of(0, 0));
92-
assertThat(distance).isEqualByComparingTo(ShrinkingDistance.MIN);
91+
assertThat(distance).isEqualTo(ShrinkingDistance.MIN);
9392
}
9493

9594
@Example

0 commit comments

Comments
 (0)