DATACMNS-1366 - Performance improvements in mapping subsystem
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.
This commit is contained in:
committed by
Oliver Gierke
parent
e50e013964
commit
4600190d01
@@ -105,7 +105,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
|
||||
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));
|
||||
@@ -507,7 +507,21 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
|
||||
*/
|
||||
@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) {
|
||||
|
||||
@@ -30,8 +30,8 @@ import java.util.Set;
|
||||
|
||||
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}.
|
||||
@@ -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));
|
||||
@@ -67,7 +68,7 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -549,7 +549,15 @@ class TypeDiscoverer<S> implements TypeInformation<S> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user