From bd432e731100aa299d5564f930efcb91e0ee57e9 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 29 Jan 2020 01:39:50 +0100 Subject: [PATCH] Do not use singleton ImmutableMap for datatree/schematree As it turns out singleton ImmutableMap has a few kinks, one of which is allocating its inverse when asked for values. This is consting us 48 bytes more than with Collections.singletonMap(), hence let's special case to bring our footprint down. JIRA: YANGTOOLS-652 Change-Id: I7ac170c02609a15b3ec77a91e5075ec62f814232 Signed-off-by: Robert Varga (cherry picked from commit e61246c419cd0655ca9dccdcd9e497440324d7b7) --- .../AbstractDeclaredEffectiveStatement.java | 17 +++++----- ...AbstractSchemaEffectiveDocumentedNode.java | 31 ++++++++++++++----- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredEffectiveStatement.java index fe88538bf0..c6987477ee 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredEffectiveStatement.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredEffectiveStatement.java @@ -12,7 +12,6 @@ import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import java.util.Map; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; @@ -84,7 +83,7 @@ public abstract class AbstractDeclaredEffectiveStatement> schemaTreeNamespace(); + protected abstract Map> schemaTreeNamespace(); } /** @@ -107,7 +106,7 @@ public abstract class AbstractDeclaredEffectiveStatement> dataTreeNamespace(); + protected abstract Map> dataTreeNamespace(); } /** @@ -176,7 +175,7 @@ public abstract class AbstractDeclaredEffectiveStatement, E extends SchemaTreeAwareEffectiveStatement> extends WithSchemaTree { - private final @NonNull ImmutableMap> schemaTree; + private final @NonNull Map> schemaTree; private final @NonNull D declared; protected DefaultWithSchemaTree(final D declared, final StmtContext ctx, @@ -192,7 +191,7 @@ public abstract class AbstractDeclaredEffectiveStatement> schemaTreeNamespace() { + protected final Map> schemaTreeNamespace() { return schemaTree; } } @@ -207,8 +206,8 @@ public abstract class AbstractDeclaredEffectiveStatement, E extends DataTreeAwareEffectiveStatement> extends WithDataTree { - private final @NonNull ImmutableMap> schemaTree; - private final @NonNull ImmutableMap> dataTree; + private final @NonNull Map> schemaTree; + private final @NonNull Map> dataTree; private final @NonNull D declared; protected DefaultWithDataTree(final D declared, final StmtContext ctx, @@ -225,12 +224,12 @@ public abstract class AbstractDeclaredEffectiveStatement> schemaTreeNamespace() { + protected final Map> schemaTreeNamespace() { return schemaTree; } @Override - protected final ImmutableMap> dataTreeNamespace() { + protected final Map> dataTreeNamespace() { return dataTree; } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractSchemaEffectiveDocumentedNode.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractSchemaEffectiveDocumentedNode.java index 79ae09fee6..6b2ca676b5 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractSchemaEffectiveDocumentedNode.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractSchemaEffectiveDocumentedNode.java @@ -15,8 +15,10 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.lang.invoke.VarHandle; import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; @@ -45,8 +47,8 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReferenc @Beta public abstract class AbstractSchemaEffectiveDocumentedNode> extends AbstractEffectiveDocumentedNode { - private final ImmutableMap> dataTreeNamespace; - private final ImmutableMap> schemaTreeNamespace; + private final Map> dataTreeNamespace; + private final Map> schemaTreeNamespace; protected AbstractSchemaEffectiveDocumentedNode(final StmtContext ctx) { super(ctx); @@ -97,17 +99,17 @@ public abstract class AbstractSchemaEffectiveDocumentedNode> createSchemaTreeNamespace( + static @NonNull Map> createSchemaTreeNamespace( final StatementSourceReference ref, final Collection> substatements) { final Map> schemaChildren = new LinkedHashMap<>(); substatements.stream().filter(SchemaTreeEffectiveStatement.class::isInstance) .forEach(child -> putChild(schemaChildren, (SchemaTreeEffectiveStatement) child, ref, "schema")); - return ImmutableMap.copyOf(schemaChildren); + return toImmutable(schemaChildren); } - static @NonNull ImmutableMap> createDataTreeNamespace( + static @NonNull Map> createDataTreeNamespace( final StatementSourceReference ref, - final ImmutableMap> schemaTreeNamespace) { + final Map> schemaTreeNamespace) { final Map> dataChildren = new LinkedHashMap<>(); boolean sameAsSchema = true; @@ -122,7 +124,22 @@ public abstract class AbstractSchemaEffectiveDocumentedNode Map toImmutable(final Map map) { + switch (map.size()) { + case 0: + return ImmutableMap.of(); + case 1: + // Special case: singleton ImmutableMap is actually SingletonImmutableBiMap, which allocates its inverse + // view and its keySet() when asked for values() -- which costs us 64 bytes (40+24). + // java.util.Collections can do the same job for less memory. + final Entry entry = map.entrySet().iterator().next(); + return Collections.singletonMap(entry.getKey(), entry.getValue()); + default: + return ImmutableMap.copyOf(map); + } } @SuppressWarnings("unchecked") -- 2.36.6