Skip to content

Commit

Permalink
DATACMNS-1366 - Performance improvements in mapping subsystem
Browse files Browse the repository at this point in the history
We now use a presized HashMap and Weak references in BasicPersistentEntity to improve memory and CPU profile and and avoid unmodifiable collection creation in BasicPersistentEntity.iterator(). Refactored ClassTypeInformation.from(…) lambda to method reference and predefined collection size for the cache. Reduced object instantiations during TypeDiscoverer.equals(…) by checking for type variable map emptiness to avoid Map iterator creation in Map.equals(…).

Original pull request: #305.
  • Loading branch information
mp911de authored and odrotbohm committed Aug 15, 2018
1 parent e50e013 commit 92f2e6b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
Expand Up @@ -105,7 +105,7 @@ public BasicPersistentEntity(TypeInformation<T> information, @Nullable Comparato
this.constructor = PreferredConstructorDiscoverer.discover(this);
this.associations = comparator == null ? new HashSet<>() : new TreeSet<>(new AssociationComparator<>(comparator));

this.propertyCache = new HashMap<>();
this.propertyCache = new HashMap<>(16, 1f);
this.annotationCache = new ConcurrentReferenceHashMap<>(16, ReferenceType.WEAK);
this.propertyAnnotationCache = CollectionUtils
.toMultiValueMap(new ConcurrentReferenceHashMap<>(16, ReferenceType.WEAK));
Expand Down Expand Up @@ -507,7 +507,21 @@ public boolean requiresPropertyPopulation() {
*/
@Override
public Iterator<P> iterator() {
return Collections.unmodifiableList(properties).iterator();

Iterator<P> iterator = properties.iterator();

return new Iterator<P>() {

@Override
public boolean hasNext() {
return iterator.hasNext();
}

@Override
public P next() {
return iterator.next();
}
};
}

protected EvaluationContext getEvaluationContext(Object rootObject) {
Expand Down
Expand Up @@ -30,8 +30,8 @@

import org.springframework.core.GenericTypeResolver;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType;

/**
* {@link TypeInformation} for a plain {@link Class}.
Expand All @@ -48,7 +48,8 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
public static final ClassTypeInformation<Map> MAP = new ClassTypeInformation(Map.class);
public static final ClassTypeInformation<Object> OBJECT = new ClassTypeInformation(Object.class);

private static final Map<Class<?>, ClassTypeInformation<?>> CACHE = new ConcurrentReferenceHashMap<>();
private static final Map<Class<?>, ClassTypeInformation<?>> CACHE = new ConcurrentReferenceHashMap<>(16,
ReferenceType.WEAK);

static {
Arrays.asList(COLLECTION, LIST, SET, MAP, OBJECT).forEach(it -> CACHE.put(it.getType(), it));
Expand All @@ -67,7 +68,7 @@ public static <S> ClassTypeInformation<S> from(Class<S> type) {

Assert.notNull(type, "Type must not be null!");

return (ClassTypeInformation<S>) CACHE.computeIfAbsent(type, it -> new ClassTypeInformation<>(type));
return (ClassTypeInformation<S>) CACHE.computeIfAbsent(type, ClassTypeInformation::new);
}

/**
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/org/springframework/data/util/TypeDiscoverer.java
Expand Up @@ -549,7 +549,15 @@ public boolean equals(@Nullable Object obj) {

TypeDiscoverer<?> that = (TypeDiscoverer<?>) obj;

return this.type.equals(that.type) && this.typeVariableMap.equals(that.typeVariableMap);
if (!this.type.equals(that.type)) {
return false;
}

if (this.typeVariableMap.isEmpty() && that.typeVariableMap.isEmpty()) {
return true;
}

return this.typeVariableMap.equals(that.typeVariableMap);
}

/*
Expand Down

0 comments on commit 92f2e6b

Please sign in to comment.