From 9f72f1c251b02fe484290448c74db6a81dd6bf21 Mon Sep 17 00:00:00 2001 From: zml Date: Sun, 11 Jul 2021 12:09:53 -0700 Subject: [PATCH] core: Optimize TypeSerializerCollection.get This was showing up quite heavily in some end user profiles --- .../serialize/TypeSerializerCollection.java | 47 ++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/spongepowered/configurate/serialize/TypeSerializerCollection.java b/core/src/main/java/org/spongepowered/configurate/serialize/TypeSerializerCollection.java index 12e00901d..932fc684c 100644 --- a/core/src/main/java/org/spongepowered/configurate/serialize/TypeSerializerCollection.java +++ b/core/src/main/java/org/spongepowered/configurate/serialize/TypeSerializerCollection.java @@ -16,7 +16,6 @@ */ package org.spongepowered.configurate.serialize; -import static io.leangen.geantyref.GenericTypeReflector.annotate; import static io.leangen.geantyref.GenericTypeReflector.isSuperType; import static java.util.Objects.requireNonNull; import static org.spongepowered.configurate.util.Types.requireCompleteParameters; @@ -24,6 +23,7 @@ import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.TypeToken; import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.ObjectMapper; import org.spongepowered.configurate.util.UnmodifiableCollections; @@ -82,7 +82,7 @@ public final class TypeSerializerCollection { } private final @Nullable TypeSerializerCollection parent; - private final List serializers; + final List serializers; private final Map> typeMatches = new ConcurrentHashMap<>(); private TypeSerializerCollection(final @Nullable TypeSerializerCollection parent, final List serializers) { @@ -106,7 +106,7 @@ private TypeSerializerCollection(final @Nullable TypeSerializerCollection parent @SuppressWarnings("unchecked") public @Nullable TypeSerializer get(final TypeToken token) { requireNonNull(token, "type"); - return (TypeSerializer) get(token.getType()); + return (TypeSerializer) get0(token.getType()); } /** @@ -143,19 +143,26 @@ private TypeSerializerCollection(final @Nullable TypeSerializerCollection parent * serializer is found * @since 4.0.0 */ - public @Nullable TypeSerializer get(Type type) { - type = GenericTypeReflector.toCanonicalBoxed(annotate(requireNonNull(type, "type"))).getType(); - @Nullable TypeSerializer serial = this.typeMatches.computeIfAbsent(type, param -> { + public @Nullable TypeSerializer get(final Type type) { + return this.get0(GenericTypeReflector.box(type)); + } + + private @Nullable TypeSerializer get0(final Type canonical) { + @Nullable TypeSerializer serial = this.typeMatches.computeIfAbsent(canonical, param -> { for (RegisteredSerializer ent : this.serializers) { if (ent.predicate.test(param)) { return ent.serializer; } } - return null; + return NoOp.INSTANCE; }); + if (serial == NoOp.INSTANCE) { + serial = null; + } + if (serial == null && this.parent != null) { - serial = this.parent.get(type); + serial = this.parent.get0(canonical); } return serial; } @@ -432,10 +439,10 @@ public TypeSerializerCollection build() { } } - private static final class RegisteredSerializer { + static final class RegisteredSerializer { - private final Predicate predicate; - private final TypeSerializer serializer; + final Predicate predicate; + final TypeSerializer serializer; private RegisteredSerializer(final Predicate predicate, final TypeSerializer serializer) { this.predicate = predicate; @@ -444,4 +451,22 @@ private RegisteredSerializer(final Predicate predicate, final TypeSerializ } + static final class NoOp implements TypeSerializer { + + static final NoOp INSTANCE = new NoOp(); + + private NoOp() { + } + + @Override + public Void deserialize(final Type type, final ConfigurationNode node) throws SerializationException { + throw new UnsupportedOperationException("this is a placeholder for null, should not be called directly"); + } + + @Override + public void serialize(final Type type, @Nullable final Void obj, final ConfigurationNode node) throws SerializationException { + throw new UnsupportedOperationException("this is a placeholder for null, should not be called directly"); + } + } + }