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 2cf0e65 commit 8a584ea
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
Expand Up @@ -96,7 +96,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 @@ -454,7 +454,21 @@ public IdentifierAccessor getIdentifierAccessor(Object bean) {

@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();
}
};
}

/**
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<>(64,
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 8a584ea

Please sign in to comment.