Skip to content

Commit b710226

Browse files
committed
Add smaller set first optimisation
1 parent 4256831 commit b710226

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

src/main/java/graphql/normalized/ExecutableNormalizedOperationFactory.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.google.common.collect.ImmutableListMultimap;
55
import com.google.common.collect.ImmutableMap;
66
import com.google.common.collect.ImmutableSet;
7-
import com.google.common.collect.Sets;
87
import graphql.Internal;
98
import graphql.collect.ImmutableKit;
109
import graphql.execution.CoercedVariables;
@@ -50,6 +49,7 @@
5049
import static graphql.schema.GraphQLTypeUtil.unwrapAll;
5150
import static graphql.util.FpKit.filterSet;
5251
import static graphql.util.FpKit.groupingBy;
52+
import static graphql.util.FpKit.intersection;
5353
import static java.util.Collections.singleton;
5454
import static java.util.Collections.singletonList;
5555

@@ -454,15 +454,8 @@ private Set<GraphQLObjectType> narrowDownPossibleObjects(Set<GraphQLObjectType>
454454
return resolvedTypeCondition;
455455
}
456456

457-
// Intersection calculation is expensive when either set is large.
458-
// If a set only has one member, it is equivalent and cheaper to calculate via contains.
459-
if (resolvedTypeCondition.size() == 1 && currentOnes.contains(resolvedTypeCondition.iterator().next())) {
460-
return resolvedTypeCondition;
461-
} else if (currentOnes.size() == 1 && resolvedTypeCondition.contains(currentOnes.iterator().next())) {
462-
return currentOnes;
463-
}
464-
465-
return Sets.intersection(currentOnes, resolvedTypeCondition);
457+
// Faster intersection, as either set often has a size of 1.
458+
return intersection(currentOnes, resolvedTypeCondition);
466459
}
467460

468461
private ImmutableSet<GraphQLObjectType> resolvePossibleObjects(List<GraphQLFieldDefinition> defs, GraphQLSchema graphQLSchema) {

src/main/java/graphql/util/FpKit.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
import com.google.common.collect.ImmutableList;
55
import com.google.common.collect.ImmutableSet;
6+
import com.google.common.collect.Sets;
67
import graphql.Internal;
78

89
import java.lang.reflect.Array;
910
import java.util.ArrayList;
1011
import java.util.Collection;
1112
import java.util.Iterator;
1213
import java.util.LinkedHashMap;
13-
import java.util.LinkedHashSet;
1414
import java.util.List;
1515
import java.util.Map;
1616
import java.util.NoSuchElementException;
@@ -330,4 +330,27 @@ public static <T> Supplier<T> interThreadMemoize(Supplier<T> delegate) {
330330
return new InterThreadMemoizedSupplier<>(delegate);
331331
}
332332

333+
/**
334+
* Faster set intersection.
335+
*
336+
* @param set1 first set
337+
* @param set2 second set
338+
* @return intersection set
339+
*/
340+
public static <T> Set<T> intersection(Set<T> set1, Set<T> set2) {
341+
// Set intersection calculation is expensive when either set is large. Often, either set has only one member.
342+
// When either set contains only one member, it is equivalent and much cheaper to calculate intersection via contains.
343+
if (set1.size() == 1 && set2.contains(set1.iterator().next())) {
344+
return set1;
345+
} else if (set2.size() == 1 && set1.contains(set2.iterator().next())) {
346+
return set2;
347+
}
348+
349+
// Guava's Sets.intersection is faster when the smaller set is passed as the first argument.
350+
if (set1.size() < set2.size()) {
351+
return Sets.intersection(set1, set2);
352+
}
353+
return Sets.intersection(set2, set1);
354+
}
355+
333356
}

0 commit comments

Comments
 (0)