From 8a584eaa9ec829f862eb528db61199bc4db20187 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 8 Aug 2018 11:49:27 +0200 Subject: [PATCH] DATACMNS-1366 - Performance improvements in mapping subsystem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../mapping/model/BasicPersistentEntity.java | 18 ++++++++++++++++-- .../data/util/ClassTypeInformation.java | 7 ++++--- .../data/util/TypeDiscoverer.java | 10 +++++++++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java index e37ef8a50..f022fad27 100644 --- a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java @@ -96,7 +96,7 @@ public class BasicPersistentEntity> 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)); @@ -454,7 +454,21 @@ public class BasicPersistentEntity> implement @Override public Iterator

iterator() { - return Collections.unmodifiableList(properties).iterator(); + + Iterator

iterator = properties.iterator(); + + return new Iterator

() { + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public P next() { + return iterator.next(); + } + }; } /** diff --git a/src/main/java/org/springframework/data/util/ClassTypeInformation.java b/src/main/java/org/springframework/data/util/ClassTypeInformation.java index a8c8aac50..118e39c10 100644 --- a/src/main/java/org/springframework/data/util/ClassTypeInformation.java +++ b/src/main/java/org/springframework/data/util/ClassTypeInformation.java @@ -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 extends TypeDiscoverer { public static final ClassTypeInformation MAP = new ClassTypeInformation(Map.class); public static final ClassTypeInformation OBJECT = new ClassTypeInformation(Object.class); - private static final Map, ClassTypeInformation> CACHE = new ConcurrentReferenceHashMap<>(); + private static final Map, 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 extends TypeDiscoverer { Assert.notNull(type, "Type must not be null!"); - return (ClassTypeInformation) CACHE.computeIfAbsent(type, it -> new ClassTypeInformation<>(type)); + return (ClassTypeInformation) CACHE.computeIfAbsent(type, ClassTypeInformation::new); } /** diff --git a/src/main/java/org/springframework/data/util/TypeDiscoverer.java b/src/main/java/org/springframework/data/util/TypeDiscoverer.java index 2f06a7884..7dc796a9c 100644 --- a/src/main/java/org/springframework/data/util/TypeDiscoverer.java +++ b/src/main/java/org/springframework/data/util/TypeDiscoverer.java @@ -549,7 +549,15 @@ class TypeDiscoverer implements TypeInformation { 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); } /*