Skip to content

Commit

Permalink
Inline toString memoization in Key.
Browse files Browse the repository at this point in the history
This decreases the cost of toString slightly (~20.97ns->~14.31ns) and removes the
Suppliers (2 objects per key).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=115866891
  • Loading branch information
lukesandberg authored and sameb committed Jun 13, 2016
1 parent 9f0fb56 commit bd1363a
Showing 1 changed file with 12 additions and 22 deletions.
34 changes: 12 additions & 22 deletions core/src/com/google/inject/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import static com.google.inject.internal.Annotations.generateAnnotation;
import static com.google.inject.internal.Annotations.isAllDefaultMethods;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.inject.internal.Annotations;
import com.google.inject.internal.MoreTypes;

Expand Down Expand Up @@ -58,7 +56,10 @@ public class Key<T> {

private final TypeLiteral<T> typeLiteral;
private final int hashCode;
private final Supplier<String> toStringSupplier;
// This field is updated using the 'Data-Race-Ful' lazy intialization pattern
// See http://jeremymanson.blogspot.com/2008/12/benign-data-races-in-java.html for a detailed
// explanation.
private String toString;

/**
* Constructs a new key. Derives the type from this class's type parameter.
Expand All @@ -78,7 +79,6 @@ protected Key(Class<? extends Annotation> annotationType) {
this.typeLiteral = MoreTypes.canonicalizeForKey(
(TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}

/**
Expand All @@ -100,7 +100,6 @@ protected Key(Annotation annotation) {
this.typeLiteral = MoreTypes.canonicalizeForKey(
(TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}

/**
Expand All @@ -120,7 +119,6 @@ protected Key() {
this.typeLiteral = MoreTypes.canonicalizeForKey(
(TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}

/**
Expand All @@ -131,15 +129,13 @@ private Key(Type type, AnnotationStrategy annotationStrategy) {
this.annotationStrategy = annotationStrategy;
this.typeLiteral = MoreTypes.canonicalizeForKey((TypeLiteral<T>) TypeLiteral.get(type));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}

/** Constructs a key from a manually specified type. */
private Key(TypeLiteral<T> typeLiteral, AnnotationStrategy annotationStrategy) {
this.annotationStrategy = annotationStrategy;
this.typeLiteral = MoreTypes.canonicalizeForKey(typeLiteral);
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}

/**
Expand All @@ -149,19 +145,6 @@ private int computeHashCode() {
return typeLiteral.hashCode() * 31 + annotationStrategy.hashCode();
}

/**
* @return a {@link Supplier} which memoizes the value for lazy initialization.
*/
private Supplier<String> createToStringSupplier() {
// The performance hit on access is acceptable since the intended use is for non-performance-
// critical applications such as debugging and logging.
return Suppliers.memoize(new Supplier<String>() {
@Override public String get() {
return "Key[type=" + typeLiteral + ", annotation=" + annotationStrategy + "]";
}
});
}

/**
* Gets the key type.
*/
Expand Down Expand Up @@ -225,7 +208,14 @@ Key<Provider<T>> providerKey() {
}

@Override public final String toString() {
return toStringSupplier.get();
// Note: to not introduce dangerous data races the field should only be read once in this
// method.
String local = toString;
if (local == null) {
local = "Key[type=" + typeLiteral + ", annotation=" + annotationStrategy + "]";
toString = local;
}
return local;
}

/**
Expand Down

0 comments on commit bd1363a

Please sign in to comment.