1 /* 2 * Copyright (C) 2012 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.Preconditions.checkState; 20 21 import com.google.common.base.Equivalence; 22 import java.util.Collection; 23 import java.util.Collections; 24 import java.util.HashSet; 25 import java.util.LinkedHashSet; 26 import java.util.Map; 27 import java.util.Queue; 28 import java.util.Random; 29 import java.util.Set; 30 import java.util.SortedMap; 31 import java.util.TreeSet; 32 import java.util.concurrent.ConcurrentHashMap; 33 import java.util.concurrent.ConcurrentMap; 34 import java.util.concurrent.ConcurrentSkipListMap; 35 36 /** 37 * Helper classes for various benchmarks. 38 * 39 * @author Christopher Swenson 40 */ 41 final class BenchmarkHelpers { 42 /** So far, this is the best way to test various implementations of {@link Set} subclasses. */ 43 public interface CollectionsImplEnum { create(Collection<E> contents)44 <E extends Comparable<E>> Collection<E> create(Collection<E> contents); 45 name()46 String name(); 47 } 48 49 public interface MapsImplEnum { create(Map<K, V> contents)50 <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> contents); 51 name()52 String name(); 53 } 54 55 public interface InternerImplEnum { create(Collection<E> contents)56 <E> Interner<E> create(Collection<E> contents); 57 name()58 String name(); 59 } 60 61 public enum SetImpl implements CollectionsImplEnum { 62 HashSetImpl { 63 @Override create(Collection<E> contents)64 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 65 return new HashSet<E>(contents); 66 } 67 }, 68 LinkedHashSetImpl { 69 @Override create(Collection<E> contents)70 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 71 return new LinkedHashSet<E>(contents); 72 } 73 }, 74 TreeSetImpl { 75 @Override create(Collection<E> contents)76 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 77 return new TreeSet<E>(contents); 78 } 79 }, 80 UnmodifiableSetImpl { 81 @Override create(Collection<E> contents)82 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 83 return Collections.unmodifiableSet(new HashSet<E>(contents)); 84 } 85 }, 86 SynchronizedSetImpl { 87 @Override create(Collection<E> contents)88 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 89 return Collections.synchronizedSet(new HashSet<E>(contents)); 90 } 91 }, 92 ImmutableSetImpl { 93 @Override create(Collection<E> contents)94 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 95 return ImmutableSet.copyOf(contents); 96 } 97 }, 98 ImmutableSortedSetImpl { 99 @Override create(Collection<E> contents)100 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 101 return ImmutableSortedSet.copyOf(contents); 102 } 103 }, 104 ContiguousSetImpl { 105 @Override create(Collection<E> contents)106 public <E extends Comparable<E>> Set<E> create(Collection<E> contents) { 107 return ContiguousSet.copyOf(contents); 108 } 109 }, 110 ; 111 } 112 113 public enum ListMultimapImpl { 114 ArrayListMultimapImpl { 115 @Override create(Multimap<K, V> contents)116 <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) { 117 return ArrayListMultimap.create(contents); 118 } 119 }, 120 LinkedListMultimapImpl { 121 @Override create(Multimap<K, V> contents)122 <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) { 123 return LinkedListMultimap.create(contents); 124 } 125 }, 126 ImmutableListMultimapImpl { 127 @Override create(Multimap<K, V> contents)128 <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) { 129 return ImmutableListMultimap.copyOf(contents); 130 } 131 }; 132 create(Multimap<K, V> contents)133 abstract <K, V> ListMultimap<K, V> create(Multimap<K, V> contents); 134 } 135 136 public enum RangeSetImpl { 137 TreeRangeSetImpl { 138 @Override create(RangeSet<K> contents)139 <K extends Comparable<K>> RangeSet<K> create(RangeSet<K> contents) { 140 return TreeRangeSet.create(contents); 141 } 142 }, 143 ImmutableRangeSetImpl { 144 @Override create(RangeSet<K> contents)145 <K extends Comparable<K>> RangeSet<K> create(RangeSet<K> contents) { 146 return ImmutableRangeSet.copyOf(contents); 147 } 148 }; 149 create(RangeSet<K> contents)150 abstract <K extends Comparable<K>> RangeSet<K> create(RangeSet<K> contents); 151 } 152 153 public enum SetMultimapImpl { 154 HashMultimapImpl { 155 @Override create( Multimap<K, V> contents)156 <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create( 157 Multimap<K, V> contents) { 158 return HashMultimap.create(contents); 159 } 160 }, 161 LinkedHashMultimapImpl { 162 @Override create( Multimap<K, V> contents)163 <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create( 164 Multimap<K, V> contents) { 165 return LinkedHashMultimap.create(contents); 166 } 167 }, 168 TreeMultimapImpl { 169 @Override create( Multimap<K, V> contents)170 <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create( 171 Multimap<K, V> contents) { 172 return TreeMultimap.create(contents); 173 } 174 }, 175 ImmutableSetMultimapImpl { 176 @Override create( Multimap<K, V> contents)177 <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create( 178 Multimap<K, V> contents) { 179 return ImmutableSetMultimap.copyOf(contents); 180 } 181 }; 182 create( Multimap<K, V> contents)183 abstract <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create( 184 Multimap<K, V> contents); 185 } 186 187 public enum MapImpl implements MapsImplEnum { 188 HashMapImpl { 189 @Override create(Map<K, V> map)190 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 191 return Maps.newHashMap(map); 192 } 193 }, 194 LinkedHashMapImpl { 195 @Override create(Map<K, V> map)196 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 197 return Maps.newLinkedHashMap(map); 198 } 199 }, 200 ConcurrentHashMapImpl { 201 @Override create(Map<K, V> map)202 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 203 return new ConcurrentHashMap<>(map); 204 } 205 }, 206 ImmutableMapImpl { 207 @Override create(Map<K, V> map)208 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 209 return ImmutableMap.copyOf(map); 210 } 211 }, 212 MapMakerStrongKeysStrongValues { 213 @Override create(Map<K, V> map)214 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 215 // We use a "custom" equivalence to force MapMaker to make a MapMakerInternalMap. 216 ConcurrentMap<K, V> newMap = new MapMaker().keyEquivalence(Equivalence.equals()).makeMap(); 217 checkState(newMap instanceof MapMakerInternalMap); 218 newMap.putAll(map); 219 return newMap; 220 } 221 }, 222 MapMakerStrongKeysWeakValues { 223 @Override create(Map<K, V> map)224 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 225 ConcurrentMap<K, V> newMap = new MapMaker().weakValues().makeMap(); 226 checkState(newMap instanceof MapMakerInternalMap); 227 newMap.putAll(map); 228 return newMap; 229 } 230 }, 231 MapMakerWeakKeysStrongValues { 232 @Override create(Map<K, V> map)233 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 234 ConcurrentMap<K, V> newMap = new MapMaker().weakKeys().makeMap(); 235 checkState(newMap instanceof MapMakerInternalMap); 236 newMap.putAll(map); 237 return newMap; 238 } 239 }, 240 MapMakerWeakKeysWeakValues { 241 @Override create(Map<K, V> map)242 public <K extends Comparable<K>, V> Map<K, V> create(Map<K, V> map) { 243 ConcurrentMap<K, V> newMap = new MapMaker().weakKeys().weakValues().makeMap(); 244 checkState(newMap instanceof MapMakerInternalMap); 245 newMap.putAll(map); 246 return newMap; 247 } 248 }; 249 } 250 251 enum SortedMapImpl implements MapsImplEnum { 252 TreeMapImpl { 253 @Override create(Map<K, V> map)254 public <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) { 255 SortedMap<K, V> result = Maps.newTreeMap(); 256 result.putAll(map); 257 return result; 258 } 259 }, 260 ConcurrentSkipListImpl { 261 @Override create(Map<K, V> map)262 public <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) { 263 return new ConcurrentSkipListMap<>(map); 264 } 265 }, 266 ImmutableSortedMapImpl { 267 @Override create(Map<K, V> map)268 public <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) { 269 return ImmutableSortedMap.copyOf(map); 270 } 271 }; 272 } 273 274 enum BiMapImpl implements MapsImplEnum { 275 HashBiMapImpl { 276 @Override create(Map<K, V> map)277 public <K extends Comparable<K>, V> BiMap<K, V> create(Map<K, V> map) { 278 return HashBiMap.create(map); 279 } 280 }, 281 ImmutableBiMapImpl { 282 @Override create(Map<K, V> map)283 public <K extends Comparable<K>, V> BiMap<K, V> create(Map<K, V> map) { 284 return ImmutableBiMap.copyOf(map); 285 } 286 }; 287 288 @Override create(Map<K, V> map)289 public abstract <K extends Comparable<K>, V> BiMap<K, V> create(Map<K, V> map); 290 } 291 292 enum MultisetImpl implements CollectionsImplEnum { 293 HashMultisetImpl { 294 @Override create(Collection<E> contents)295 public <E extends Comparable<E>> Multiset<E> create(Collection<E> contents) { 296 return HashMultiset.create(contents); 297 } 298 }, 299 LinkedHashMultisetImpl { 300 @Override create(Collection<E> contents)301 public <E extends Comparable<E>> Multiset<E> create(Collection<E> contents) { 302 return LinkedHashMultiset.create(contents); 303 } 304 }, 305 ConcurrentHashMultisetImpl { 306 @Override create(Collection<E> contents)307 public <E extends Comparable<E>> Multiset<E> create(Collection<E> contents) { 308 return ConcurrentHashMultiset.create(contents); 309 } 310 }, 311 ImmutableMultisetImpl { 312 @Override create(Collection<E> contents)313 public <E extends Comparable<E>> Multiset<E> create(Collection<E> contents) { 314 return ImmutableMultiset.copyOf(contents); 315 } 316 }; 317 } 318 319 enum SortedMultisetImpl implements CollectionsImplEnum { 320 TreeMultisetImpl { 321 @Override create(Collection<E> contents)322 public <E extends Comparable<E>> SortedMultiset<E> create(Collection<E> contents) { 323 return TreeMultiset.create(contents); 324 } 325 }, 326 ImmutableSortedMultisetImpl { 327 @Override create(Collection<E> contents)328 public <E extends Comparable<E>> SortedMultiset<E> create(Collection<E> contents) { 329 return ImmutableSortedMultiset.copyOf(contents); 330 } 331 }; 332 } 333 334 enum QueueImpl implements CollectionsImplEnum { 335 MinMaxPriorityQueueImpl { 336 @Override create(Collection<E> contents)337 public <E extends Comparable<E>> Queue<E> create(Collection<E> contents) { 338 return MinMaxPriorityQueue.create(contents); 339 } 340 }; 341 } 342 343 enum TableImpl { 344 HashBasedTableImpl { 345 @Override create( Table<R, C, V> contents)346 <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create( 347 Table<R, C, V> contents) { 348 return HashBasedTable.create(contents); 349 } 350 }, 351 TreeBasedTableImpl { 352 @Override create( Table<R, C, V> contents)353 <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create( 354 Table<R, C, V> contents) { 355 Table<R, C, V> table = TreeBasedTable.create(); 356 table.putAll(contents); 357 return table; 358 } 359 }, 360 ArrayTableImpl { 361 @Override create( Table<R, C, V> contents)362 <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create( 363 Table<R, C, V> contents) { 364 if (contents.isEmpty()) { 365 return ImmutableTable.of(); 366 } else { 367 return ArrayTable.create(contents); 368 } 369 } 370 }, 371 ImmutableTableImpl { 372 @Override create( Table<R, C, V> contents)373 <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create( 374 Table<R, C, V> contents) { 375 return ImmutableTable.copyOf(contents); 376 } 377 }; 378 create( Table<R, C, V> contents)379 abstract <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create( 380 Table<R, C, V> contents); 381 } 382 383 public enum InternerImpl implements InternerImplEnum { 384 WeakInternerImpl { 385 @Override create(Collection<E> contents)386 public <E> Interner<E> create(Collection<E> contents) { 387 Interner<E> interner = Interners.newWeakInterner(); 388 for (E e : contents) { 389 interner.intern(e); 390 } 391 return interner; 392 } 393 }, 394 StrongInternerImpl { 395 @Override create(Collection<E> contents)396 public <E> Interner<E> create(Collection<E> contents) { 397 Interner<E> interner = Interners.newStrongInterner(); 398 for (E e : contents) { 399 interner.intern(e); 400 } 401 return interner; 402 } 403 }; 404 } 405 406 public enum Value { 407 INSTANCE; 408 } 409 410 public enum ListSizeDistribution { 411 UNIFORM_0_TO_2(0, 2), 412 UNIFORM_0_TO_9(0, 9), 413 ALWAYS_0(0, 0), 414 ALWAYS_10(10, 10); 415 416 final int min; 417 final int max; 418 ListSizeDistribution(int min, int max)419 private ListSizeDistribution(int min, int max) { 420 this.min = min; 421 this.max = max; 422 } 423 chooseSize(Random random)424 public int chooseSize(Random random) { 425 return random.nextInt(max - min + 1) + min; 426 } 427 } 428 } 429