Use OptionalInt instead of Optional<Integer> (#34220)

Optionals containing boxed primitive types are prohibitively costly because they
have two level of boxing. For Optional<Integer> the analogous OptionalInt can be
used to avoid the boxing of the contained int value.
This commit is contained in:
Christoph Büscher 2018-10-02 15:58:07 +02:00 committed by GitHub
parent 2ba18f50a8
commit 5183ea3d68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 66 additions and 58 deletions

View File

@ -90,7 +90,7 @@ public class RankEvalIT extends ESRestHighLevelClientTestCase {
if (id.equals("berlin") || id.equals("amsterdam5")) {
assertFalse(hit.getRating().isPresent());
} else {
assertEquals(1, hit.getRating().get().intValue());
assertEquals(1, hit.getRating().getAsInt());
}
}
EvalQueryQuality berlinQueryQuality = partialResults.get("berlin_query");
@ -100,7 +100,7 @@ public class RankEvalIT extends ESRestHighLevelClientTestCase {
for (RatedSearchHit hit : hitsAndRatings) {
String id = hit.getSearchHit().getId();
if (id.equals("berlin")) {
assertEquals(1, hit.getRating().get().intValue());
assertEquals(1, hit.getRating().getAsInt());
} else {
assertFalse(hit.getRating().isPresent());
}

View File

@ -33,7 +33,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
@ -119,8 +119,8 @@ public class DiscountedCumulativeGain implements EvaluationMetric {
@Override
public Optional<Integer> forcedSearchSize() {
return Optional.of(k);
public OptionalInt forcedSearchSize() {
return OptionalInt.of(k);
}
@Override
@ -130,9 +130,13 @@ public class DiscountedCumulativeGain implements EvaluationMetric {
List<Integer> ratingsInSearchHits = new ArrayList<>(ratedHits.size());
int unratedResults = 0;
for (RatedSearchHit hit : ratedHits) {
// unknownDocRating might be null, in which case unrated docs will be ignored in the dcg calculation.
// we still need to add them as a placeholder so the rank of the subsequent ratings is correct
ratingsInSearchHits.add(hit.getRating().orElse(unknownDocRating));
if (hit.getRating().isPresent()) {
ratingsInSearchHits.add(hit.getRating().getAsInt());
} else {
// unknownDocRating might be null, in which case unrated docs will be ignored in the dcg calculation.
// we still need to add them as a placeholder so the rank of the subsequent ratings is correct
ratingsInSearchHits.add(unknownDocRating);
}
if (hit.getRating().isPresent() == false) {
unratedResults++;
}

View File

@ -29,7 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Collectors;
/**
@ -64,9 +64,9 @@ public interface EvaluationMetric extends ToXContentObject, NamedWriteable {
DocumentKey key = new DocumentKey(hit.getIndex(), hit.getId());
RatedDocument ratedDoc = ratedDocumentMap.get(key);
if (ratedDoc != null) {
ratedSearchHits.add(new RatedSearchHit(hit, Optional.of(ratedDoc.getRating())));
ratedSearchHits.add(new RatedSearchHit(hit, OptionalInt.of(ratedDoc.getRating())));
} else {
ratedSearchHits.add(new RatedSearchHit(hit, Optional.empty()));
ratedSearchHits.add(new RatedSearchHit(hit, OptionalInt.empty()));
}
}
return ratedSearchHits;
@ -93,7 +93,7 @@ public interface EvaluationMetric extends ToXContentObject, NamedWriteable {
* this method. The default implementation returns an empty optional.
* @return the number of search hits this metrics requests
*/
default Optional<Integer> forcedSearchSize() {
return Optional.empty();
default OptionalInt forcedSearchSize() {
return OptionalInt.empty();
}
}

View File

@ -32,7 +32,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
@ -126,8 +126,8 @@ public class ExpectedReciprocalRank implements EvaluationMetric {
@Override
public Optional<Integer> forcedSearchSize() {
return Optional.of(k);
public OptionalInt forcedSearchSize() {
return OptionalInt.of(k);
}
@Override
@ -139,9 +139,13 @@ public class ExpectedReciprocalRank implements EvaluationMetric {
List<Integer> ratingsInSearchHits = new ArrayList<>(ratedHits.size());
int unratedResults = 0;
for (RatedSearchHit hit : ratedHits) {
// unknownDocRating might be null, in which case unrated will be ignored in the calculation.
// we still need to add them as a placeholder so the rank of the subsequent ratings is correct
ratingsInSearchHits.add(hit.getRating().orElse(unknownDocRating));
if (hit.getRating().isPresent()) {
ratingsInSearchHits.add(hit.getRating().getAsInt());
} else {
// unknownDocRating might be null, in which case unrated docs will be ignored in the dcg calculation.
// we still need to add them as a placeholder so the rank of the subsequent ratings is correct
ratingsInSearchHits.add(unknownDocRating);
}
if (hit.getRating().isPresent() == false) {
unratedResults++;
}

View File

@ -30,7 +30,7 @@ import org.elasticsearch.search.SearchHit;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
@ -90,8 +90,8 @@ public class MeanReciprocalRank implements EvaluationMetric {
}
@Override
public Optional<Integer> forcedSearchSize() {
return Optional.of(k);
public OptionalInt forcedSearchSize() {
return OptionalInt.of(k);
}
@Override
@ -115,9 +115,9 @@ public class MeanReciprocalRank implements EvaluationMetric {
int firstRelevant = -1;
int rank = 1;
for (RatedSearchHit hit : ratedHits) {
Optional<Integer> rating = hit.getRating();
OptionalInt rating = hit.getRating();
if (rating.isPresent()) {
if (rating.get() >= this.relevantRatingThreshhold) {
if (rating.getAsInt() >= this.relevantRatingThreshhold) {
firstRelevant = rank;
break;
}

View File

@ -30,7 +30,7 @@ import org.elasticsearch.search.SearchHit;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import javax.naming.directory.SearchResult;
@ -144,8 +144,8 @@ public class PrecisionAtK implements EvaluationMetric {
}
@Override
public Optional<Integer> forcedSearchSize() {
return Optional.of(k);
public OptionalInt forcedSearchSize() {
return OptionalInt.of(k);
}
public static PrecisionAtK fromXContent(XContentParser parser) {
@ -164,9 +164,9 @@ public class PrecisionAtK implements EvaluationMetric {
int falsePositives = 0;
List<RatedSearchHit> ratedSearchHits = joinHitsWithRatings(hits, ratedDocs);
for (RatedSearchHit hit : ratedSearchHits) {
Optional<Integer> rating = hit.getRating();
OptionalInt rating = hit.getRating();
if (rating.isPresent()) {
if (rating.get() >= this.relevantRatingThreshhold) {
if (rating.getAsInt() >= this.relevantRatingThreshhold) {
truePositives++;
} else {
falsePositives++;

View File

@ -33,7 +33,7 @@ import org.elasticsearch.search.SearchHit;
import java.io.IOException;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
/**
* Combines a {@link SearchHit} with a document rating.
@ -41,16 +41,16 @@ import java.util.Optional;
public class RatedSearchHit implements Writeable, ToXContentObject {
private final SearchHit searchHit;
private final Optional<Integer> rating;
private final OptionalInt rating;
public RatedSearchHit(SearchHit searchHit, Optional<Integer> rating) {
public RatedSearchHit(SearchHit searchHit, OptionalInt rating) {
this.searchHit = searchHit;
this.rating = rating;
}
RatedSearchHit(StreamInput in) throws IOException {
this(SearchHit.readSearchHit(in),
in.readBoolean() == true ? Optional.of(in.readVInt()) : Optional.empty());
in.readBoolean() == true ? OptionalInt.of(in.readVInt()) : OptionalInt.empty());
}
@Override
@ -58,7 +58,7 @@ public class RatedSearchHit implements Writeable, ToXContentObject {
searchHit.writeTo(out);
out.writeBoolean(rating.isPresent());
if (rating.isPresent()) {
out.writeVInt(rating.get());
out.writeVInt(rating.getAsInt());
}
}
@ -66,7 +66,7 @@ public class RatedSearchHit implements Writeable, ToXContentObject {
return this.searchHit;
}
public Optional<Integer> getRating() {
public OptionalInt getRating() {
return this.rating;
}
@ -75,22 +75,21 @@ public class RatedSearchHit implements Writeable, ToXContentObject {
throws IOException {
builder.startObject();
builder.field("hit", (ToXContent) searchHit);
builder.field("rating", rating.orElse(null));
builder.field("rating", rating.isPresent() ? rating.getAsInt() : null);
builder.endObject();
return builder;
}
private static final ParseField HIT_FIELD = new ParseField("hit");
private static final ParseField RATING_FIELD = new ParseField("rating");
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<RatedSearchHit, Void> PARSER = new ConstructingObjectParser<>("rated_hit", true,
a -> new RatedSearchHit((SearchHit) a[0], (Optional<Integer>) a[1]));
a -> new RatedSearchHit((SearchHit) a[0], (OptionalInt) a[1]));
static {
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> SearchHit.fromXContent(p), HIT_FIELD);
PARSER.declareField(ConstructingObjectParser.constructorArg(),
(p) -> p.currentToken() == XContentParser.Token.VALUE_NULL ? Optional.empty() : Optional.of(p.intValue()), RATING_FIELD,
ValueType.INT_OR_NULL);
(p) -> p.currentToken() == XContentParser.Token.VALUE_NULL ? OptionalInt.empty() : OptionalInt.of(p.intValue()),
RATING_FIELD, ValueType.INT_OR_NULL);
}
public static RatedSearchHit parse(XContentParser parser) throws IOException {

View File

@ -119,7 +119,7 @@ public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequ
}
if (metric.forcedSearchSize().isPresent()) {
evaluationRequest.size(metric.forcedSearchSize().get());
evaluationRequest.size(metric.forcedSearchSize().getAsInt());
}
ratedRequestsInSearch.add(ratedRequest);

View File

@ -223,7 +223,8 @@ public class PrecisionAtKTests extends ESTestCase {
}
private static PrecisionAtK copy(PrecisionAtK original) {
return new PrecisionAtK(original.getRelevantRatingThreshold(), original.getIgnoreUnlabeled(), original.forcedSearchSize().get());
return new PrecisionAtK(original.getRelevantRatingThreshold(), original.getIgnoreUnlabeled(),
original.forcedSearchSize().getAsInt());
}
private static PrecisionAtK mutate(PrecisionAtK original) {
@ -231,15 +232,15 @@ public class PrecisionAtKTests extends ESTestCase {
switch (randomIntBetween(0, 2)) {
case 0:
pAtK = new PrecisionAtK(original.getRelevantRatingThreshold(), !original.getIgnoreUnlabeled(),
original.forcedSearchSize().get());
original.forcedSearchSize().getAsInt());
break;
case 1:
pAtK = new PrecisionAtK(randomValueOtherThan(original.getRelevantRatingThreshold(), () -> randomIntBetween(0, 10)),
original.getIgnoreUnlabeled(), original.forcedSearchSize().get());
original.getIgnoreUnlabeled(), original.forcedSearchSize().getAsInt());
break;
case 2:
pAtK = new PrecisionAtK(original.getRelevantRatingThreshold(),
original.getIgnoreUnlabeled(), original.forcedSearchSize().get() + 1);
original.getIgnoreUnlabeled(), original.forcedSearchSize().getAsInt() + 1);
break;
default:
throw new IllegalStateException("The test should only allow three parameters mutated");

View File

@ -128,7 +128,7 @@ public class RankEvalRequestIT extends ESIntegTestCase {
if (id.equals("1") || id.equals("6")) {
assertFalse(hit.getRating().isPresent());
} else {
assertEquals(RELEVANT_RATING_1, hit.getRating().get().intValue());
assertEquals(RELEVANT_RATING_1, hit.getRating().getAsInt());
}
}
}
@ -139,7 +139,7 @@ public class RankEvalRequestIT extends ESIntegTestCase {
for (RatedSearchHit hit : hitsAndRatings) {
String id = hit.getSearchHit().getId();
if (id.equals("1")) {
assertEquals(RELEVANT_RATING_1, hit.getRating().get().intValue());
assertEquals(RELEVANT_RATING_1, hit.getRating().getAsInt());
} else {
assertFalse(hit.getRating().isPresent());
}

View File

@ -50,7 +50,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.function.Predicate;
import static java.util.Collections.singleton;
@ -182,6 +182,6 @@ public class RankEvalResponseTests extends ESTestCase {
SearchHit hit = new SearchHit(docId, docId + "", new Text(""), Collections.emptyMap());
hit.shard(new SearchShardTarget("testnode", new Index(index, "uuid"), 0, null));
hit.score(1.0f);
return new RatedSearchHit(hit, rating != null ? Optional.of(rating) : Optional.empty());
return new RatedSearchHit(hit, rating != null ? OptionalInt.of(rating) : OptionalInt.empty());
}
}

View File

@ -30,7 +30,7 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.Collections;
import java.util.Optional;
import java.util.OptionalInt;
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
@ -38,8 +38,8 @@ import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
public class RatedSearchHitTests extends ESTestCase {
public static RatedSearchHit randomRatedSearchHit() {
Optional<Integer> rating = randomBoolean() ? Optional.empty()
: Optional.of(randomIntBetween(0, 5));
OptionalInt rating = randomBoolean() ? OptionalInt.empty()
: OptionalInt.of(randomIntBetween(0, 5));
SearchHit searchHit = new SearchHit(randomIntBetween(0, 10), randomAlphaOfLength(10),
new Text(randomAlphaOfLength(10)), Collections.emptyMap());
RatedSearchHit ratedSearchHit = new RatedSearchHit(searchHit, rating);
@ -47,11 +47,11 @@ public class RatedSearchHitTests extends ESTestCase {
}
private static RatedSearchHit mutateTestItem(RatedSearchHit original) {
Optional<Integer> rating = original.getRating();
OptionalInt rating = original.getRating();
SearchHit hit = original.getSearchHit();
switch (randomIntBetween(0, 1)) {
case 0:
rating = rating.isPresent() ? Optional.of(rating.get() + 1) : Optional.of(randomInt(5));
rating = rating.isPresent() ? OptionalInt.of(rating.getAsInt() + 1) : OptionalInt.of(randomInt(5));
break;
case 1:
hit = new SearchHit(hit.docId(), hit.getId() + randomAlphaOfLength(10),

View File

@ -27,7 +27,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
/**
* This class acts as a functional wrapper around the {@code index.auto_expand_replicas} setting.
@ -93,7 +93,7 @@ public final class AutoExpandReplicas {
return Math.min(maxReplicas, numDataNodes-1);
}
Optional<Integer> getDesiredNumberOfReplicas(int numDataNodes) {
private OptionalInt getDesiredNumberOfReplicas(int numDataNodes) {
if (enabled) {
final int min = getMinReplicas();
final int max = getMaxReplicas(numDataNodes);
@ -105,10 +105,10 @@ public final class AutoExpandReplicas {
}
if (numberOfReplicas >= min && numberOfReplicas <= max) {
return Optional.of(numberOfReplicas);
return OptionalInt.of(numberOfReplicas);
}
}
return Optional.empty();
return OptionalInt.empty();
}
@Override