1 /*
2  * Copyright (C) 2017 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import static com.google.common.base.Functions.toStringFunction;
20 import static com.google.common.collect.Maps.uniqueIndex;
21 
22 import com.google.caliper.BeforeExperiment;
23 import com.google.caliper.Benchmark;
24 import com.google.caliper.Param;
25 import com.google.caliper.api.Footprint;
26 import com.google.common.collect.BenchmarkHelpers.BiMapImpl;
27 import com.google.common.collect.BenchmarkHelpers.MapImpl;
28 import com.google.common.collect.BenchmarkHelpers.MapsImplEnum;
29 import com.google.common.collect.BenchmarkHelpers.SortedMapImpl;
30 import com.google.common.collect.CollectionBenchmarkSampleData.Element;
31 import java.util.Arrays;
32 import java.util.Map;
33 
34 /** Benchmarks for memory consumption of map implementations. */
35 public class MapsMemoryBenchmark {
36   static final Map<String, MapsImplEnum> mapEnums =
37       uniqueIndex(
38           Iterables.<MapsImplEnum>concat(
39               Arrays.asList(MapImpl.values()),
40               Arrays.asList(SortedMapImpl.values()),
41               Arrays.asList(BiMapImpl.values())),
42           toStringFunction());
43 
44   @Param({
45     "HashMapImpl",
46     "LinkedHashMapImpl",
47     "ConcurrentHashMapImpl",
48     "CompactHashMapImpl",
49     "CompactLinkedHashMapImpl",
50     "ImmutableMapImpl",
51     "TreeMapImpl",
52     "ImmutableSortedMapImpl",
53     "MapMakerWeakKeysWeakValues",
54     "MapMakerWeakKeysStrongValues",
55     "MapMakerStrongKeysWeakValues",
56     "MapMakerStrongKeysStrongValues",
57     "HashBiMapImpl",
58     "ImmutableBiMapImpl"
59   })
60   String implName;
61 
62   MapsImplEnum mapsImpl;
63 
64   /**
65    * A map of contents pre-created before experiment starts to only measure map creation cost. The
66    * implementation for the creation of contents is independent and could be different from that of
67    * the map under test.
68    */
69   Map<Element, Element> contents;
70 
71   /** Map pre-created before experiment starts to only measure iteration cost during experiment. */
72   Map<Element, Element> map;
73 
74   CollectionBenchmarkSampleData elems;
75 
76   @Param({"0", "1", "100", "10000"})
77   int elements;
78 
79   @BeforeExperiment
prepareContents()80   public void prepareContents() throws Exception {
81     mapsImpl = mapEnums.get(implName);
82     elems = new CollectionBenchmarkSampleData(elements);
83     contents = Maps.newHashMap();
84     for (Element key : elems.getValuesInSet()) {
85       contents.put(key, key);
86     }
87     map = mapsImpl.create(contents);
88   }
89 
90   @Benchmark
91   @Footprint(exclude = Element.class)
create()92   public Map<Element, Element> create() throws Exception {
93     return mapsImpl.create(contents);
94   }
95 
96   @Benchmark
iterate()97   public int iterate() {
98     long retVal = 0;
99     for (Object entry : map.entrySet()) {
100       retVal += entry.hashCode();
101     }
102     return (int) retVal;
103   }
104 
105   @Benchmark
keyIterate()106   public int keyIterate() {
107     long retVal = 0;
108     for (Object key : map.keySet()) {
109       retVal += key.hashCode();
110     }
111     return (int) retVal;
112   }
113 }
114