From e40c27d9ed1678207c1ca4554e70ed5e2534d93f Mon Sep 17 00:00:00 2001 From: Jakob Buchgraber Date: Fri, 3 Apr 2015 10:51:29 -0700 Subject: [PATCH] Avoid object allocations for HTTP2 child streams. Motivation: We are allocating a hash map for every HTTP2 Stream to store it's children. Most streams are leafs in the priority tree and don't have children. Modification: - Only allocate children when we actually use them. - Make EmptyIntObjectMap not throw a UnsupportedOperationException on remove, but return null instead (as is stated in it's javadoc). Result: Fewer unnecessary allocations. --- .../codec/http2/DefaultHttp2Connection.java | 18 ++++++++++++------ .../util/collection/PrimitiveCollections.java | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java index e798ef3979..c99c87aeed 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java @@ -38,6 +38,7 @@ import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http2.Http2StreamRemovalPolicy.Action; import io.netty.util.collection.IntObjectHashMap; import io.netty.util.collection.IntObjectMap; +import io.netty.util.collection.PrimitiveCollections; import java.util.ArrayList; import java.util.Collection; @@ -216,7 +217,7 @@ public class DefaultHttp2Connection implements Http2Connection { private State state = IDLE; private short weight = DEFAULT_PRIORITY_WEIGHT; private DefaultStream parent; - private IntObjectMap children = newChildMap(); + private IntObjectMap children = PrimitiveCollections.emptyIntObjectMap(); private int totalChildWeights; private int prioritizableForTree = 1; private boolean resetSent; @@ -503,6 +504,12 @@ public class DefaultHttp2Connection implements Http2Connection { } } + private void initChildrenIfEmpty() { + if (children == PrimitiveCollections.emptyIntObjectMap()) { + children = new IntObjectHashMap(4); + } + } + @Override public final boolean remoteSideOpen() { return state == HALF_CLOSED_LOCAL || state == OPEN || state == RESERVED_REMOTE; @@ -539,7 +546,7 @@ public class DefaultHttp2Connection implements Http2Connection { totalChildWeights = 0; prioritizableForTree = isPrioritizable() ? 1 : 0; IntObjectMap prevChildren = children; - children = newChildMap(); + children = PrimitiveCollections.emptyIntObjectMap(); return prevChildren; } @@ -561,6 +568,9 @@ public class DefaultHttp2Connection implements Http2Connection { } } + // Lazily initialize the children to save object allocations. + initChildrenIfEmpty(); + if (children.put(child.id(), child) == null) { totalChildWeights += child.weight(); incrementPrioritizableForTree(child.prioritizableForTree(), oldParent); @@ -673,10 +683,6 @@ public class DefaultHttp2Connection implements Http2Connection { } } - private static IntObjectMap newChildMap() { - return new IntObjectHashMap(4); - } - /** * Allows a correlation to be made between a stream and its old parent before a parent change occurs */ diff --git a/common/src/main/java/io/netty/util/collection/PrimitiveCollections.java b/common/src/main/java/io/netty/util/collection/PrimitiveCollections.java index fcb7077ae5..9903070883 100644 --- a/common/src/main/java/io/netty/util/collection/PrimitiveCollections.java +++ b/common/src/main/java/io/netty/util/collection/PrimitiveCollections.java @@ -68,7 +68,7 @@ public final class PrimitiveCollections { @Override public Object remove(int key) { - throw new UnsupportedOperationException("remove"); + return null; } @Override