diff --git a/microbench/pom.xml b/microbench/pom.xml
index a6e3101e78..d6647ad122 100644
--- a/microbench/pom.xml
+++ b/microbench/pom.xml
@@ -81,6 +81,11 @@
1.7.1
provided
+
+ uk.co.real-logic
+ Agrona
+ 0.1
+
diff --git a/microbench/src/test/java/io/netty/microbenchmark/common/IntObjectHashMapBenchmark.java b/microbench/src/test/java/io/netty/microbenchmark/common/IntObjectHashMapBenchmark.java
new file mode 100644
index 0000000000..647d2f7042
--- /dev/null
+++ b/microbench/src/test/java/io/netty/microbenchmark/common/IntObjectHashMapBenchmark.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2015 The Netty Project
+ *
+ * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package io.netty.microbenchmark.common;
+
+import io.netty.microbench.util.AbstractMicrobenchmark;
+import io.netty.util.collection.IntObjectHashMap;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.infra.Blackhole;
+import uk.co.real_logic.agrona.collections.Int2ObjectHashMap;
+
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+public class IntObjectHashMapBenchmark extends AbstractMicrobenchmark {
+ private static final Long VALUE = Long.MAX_VALUE;
+
+ public enum MapType {
+ AGRONA,
+ NETTY
+ }
+
+ public enum KeyDistribution {
+ HTTP2,
+ RANDOM
+ }
+
+ @Param({ "10", "100", "1000", "10000", "100000" })
+ public int size;
+
+ @Param
+ public MapType mapType;
+
+ @Param
+ public KeyDistribution keyDistribution;
+
+ private Environment environment;
+
+ @Setup(Level.Trial)
+ public void setup() {
+ switch(mapType) {
+ case AGRONA: {
+ environment = new AgronaEnvironment();
+ break;
+ }
+ case NETTY: {
+ environment = new NettyEnvironment();
+ break;
+ }
+ default: {
+ throw new IllegalStateException("Invalid mapType: " + mapType);
+ }
+ }
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.Throughput)
+ public void put(Blackhole bh) {
+ environment.put(bh);
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.Throughput)
+ public void lookup(Blackhole bh) {
+ environment.lookup(bh);
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.Throughput)
+ public void remove(Blackhole bh) {
+ environment.remove(bh);
+ }
+
+ private abstract class Environment {
+ final int[] keys;
+ Environment() {
+ keys = new int[size];
+ switch(keyDistribution) {
+ case HTTP2:
+ for (int index = 0, key = 3; index < size; ++index, key += 2) {
+ keys[index] = key;
+ }
+ break;
+ case RANDOM: {
+ // Create a 'size' # of random integers.
+ Random r = new Random();
+ Set keySet = new HashSet();
+ while (keySet.size() < size) {
+ keySet.add(r.nextInt());
+ }
+
+ int index = 0;
+ for (Integer key : keySet) {
+ keys[index++] = key;
+ }
+ break;
+ }
+ default: {
+ throw new IllegalStateException("Unknown keyDistribution: " + keyDistribution);
+ }
+ }
+ }
+ abstract void put(Blackhole bh);
+ abstract void lookup(Blackhole bh);
+ abstract void remove(Blackhole bh);
+ }
+
+ private class AgronaEnvironment extends Environment {
+ private final Int2ObjectHashMap map = new Int2ObjectHashMap();
+
+ AgronaEnvironment() {
+ for (int key : keys) {
+ map.put(key, VALUE);
+ }
+ }
+
+ @Override
+ void put(Blackhole bh) {
+ Int2ObjectHashMap map = new Int2ObjectHashMap();
+ for (int key : keys) {
+ bh.consume(map.put(key, VALUE));
+ }
+ }
+
+ @Override
+ void lookup(Blackhole bh) {
+ for (int key : keys) {
+ bh.consume(map.get(key));
+ }
+ }
+
+ @Override
+ void remove(Blackhole bh) {
+ Int2ObjectHashMap copy = new Int2ObjectHashMap();
+ copy.putAll(map);
+ for (int key : keys) {
+ bh.consume(copy.remove(key));
+ }
+ }
+ }
+
+ private class NettyEnvironment extends Environment {
+ private final IntObjectHashMap map = new IntObjectHashMap();
+
+ NettyEnvironment() {
+ for (int key : keys) {
+ map.put(key, VALUE);
+ }
+ }
+
+ @Override
+ void put(Blackhole bh) {
+ IntObjectHashMap map = new IntObjectHashMap();
+ for (int key : keys) {
+ bh.consume(map.put(key, VALUE));
+ }
+ }
+
+ @Override
+ void lookup(Blackhole bh) {
+ for (int key : keys) {
+ bh.consume(map.get(key));
+ }
+ }
+
+ @Override
+ void remove(Blackhole bh) {
+ IntObjectHashMap copy = new IntObjectHashMap();
+ copy.putAll(map);
+ for (int key : keys) {
+ bh.consume(copy.remove(key));
+ }
+ }
+ }
+}