Collections.compare(() -> {
JDK; Apache; Eclipse; Guava...});
Nikhil J. Nanivadekar
#CollectionsCompare #GIDS17 @NikhilNanivade
Agenda
1. Introduction
2. History of Java util collections framework
3. Gaps in use cases from the timeline
4. Timeline with other collection frameworks
5. Use case, domain diagrams
6. Deep dive in use case
7. Memory characteristics
#CollectionsCompare #GIDS17 @NikhilNanivade
Authors
• Donald Raab (@TheDonRaab)
• Leonardo Lima (@leomrlima)
• Nikhil J. Nanivadekar (@NikhilNanivade)
#CollectionsCompare #GIDS17 @NikhilNanivade
Speaker
Nikhil J. Nanivadekar
– Mechanical Engineer
– Software developer
– Vice President, Technology at Goldman Sachs
– From Pune, Maharashtra currently in Salt Lake City,
Utah
java.util Collections
#CollectionsCompare #GIDS17 @NikhilNanivade
java.util Collections
• Java Collection Framework has been around since
1998/JDK 1.2. Very basic but critical collection
support for Java.
• Interfaces: Maps and Collections (List, Set,
Queue, Deque)
• Implementations: Basic and Concurrent versions
of the interfaces, sorted and concurrent as well
• Algorithms: Sorting, Shuffling, Routine Data
Manipulation, Searching, Composition
• Best way to get started is using the simple and
concurrent tutorials
#CollectionsCompare #GIDS17 @NikhilNanivade
Java Collections Frameworks
Java 2
1998
• Interfaces
• Collection
• List
• Set
• Map
• SortedSet
• SortedMap
Java 5
2005
• Generics
• For-each loop
• Interfaces
• Iterable
• Queue
• ConcurrentMap
• BlockingQueue
Java 6
2006
•Interfaces
•NavigableSet
•NavigableMap
•Deque
•BlockingDeque
•ConcurrentNavigableMap
Java 7
2011
• Interfaces
• TransferQueue
Java 8
2014
• Lambdas
• Method Refs
• Default Methods
• Interfaces
• BaseStream
• Stream
• IntStream
• LongStream
• DoubleStream
• Collector
• Spliterator
• PrimitiveIterator
!java.util Collections?
#CollectionsCompare #GIDS17 @NikhilNanivade
!java.util Collections
• We’re considering 4 collection frameworks, in
alphabetical order:
• Apache Commons Collection
– version 4.1
• Eclipse Collections (Formerly GS Collections)
– version 8.1.0
• Google Guava
– version 21.0
• Javaslang (now called Vavr)
– version 2.1.0-alpha
#CollectionsCompare #GIDS17 @NikhilNanivade
Collection Framework Timelines
Java 2
1998
•Jakarta
Collections 1.0
•2001
•Apache Collections
3.0
•2004
Java 6
2006
•Google Collections
1.0
•Dec. 2009
Java 7
2011
•Google Guava 10.0
•Sept. 2011
•GS Collections 1.0
•Jan. 2012
•Apache Collections
4.0
•Nov. 2013
Java 8
2014
•Javaslang 1.0
•Mar. 2014
•Apache Collections 4.1
•Nov. 2015
•Eclipse Collections 7.0
•Jan. 2016
•Eclipse Collections 8.0
(Java 8)
•Sept. 2016
•Google Guava 20.0
•Oct. 2016
•Javaslang 2.1a
•Nov. 2016
March
2017
•Google Guava 21.0
(Java 8)
•Jan. 2017
•Eclipse Collections
8.1
•Mar. 2017
Collections.compare();
#CollectionsCompare #GIDS17 @NikhilNanivade
Use Case – Deck of Cards
The Collections Compare Project: https://github.com/nikhilnanivadekar/CollectionsCompare
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Benchmarks
• JMH – Java Microbenchmark Harness
• http://openjdk.java.net/projects/code-tools/jmh/
• Measure Reported – Operations per second
• Bigger numbers are better
• 4 Core Intel I7, 50 Warm-up iterations, 30
measurement iterations, two forks
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Deck of Cards
102,037
79,343 76,982
56,224
91,017
0
20,000
40,000
60,000
80,000
100,000
120,000
Scoreops/s
Framework
Deck of Cards
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Shared Code – Cartesian Product
public static Stream<Card> streamCards() {
return Card.cartesianProduct(
EnumSet.allOf(Rank.class),
EnumSet.allOf(Suit.class),
Card::new);
}
private static <A, B, C> Stream<C> cartesianProduct(
Set<A> set1,
Set<B> set2,
Function2<A, B, C> function) {
return set1.stream().flatMap(first ->
set2.stream().map(second ->
function.apply(first, second)));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Cartesian Product
185,087
203,660
465,999
127,439 114,634
0
50,000
100,000
150,000
200,000
250,000
300,000
350,000
400,000
450,000
500,000
Scoreops/s
Framework
Cartesian Product
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Cartesian Product
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
public JDK8DeckOfCards() {
this.cards = Card.streamCards()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(TreeSet::new),
Collections::unmodifiableSortedSet));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Cartesian Product
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
public ApacheCommonsDeckOfCards() {
this.cards = Card.streamCards()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(TreeSet::new),
Collections::unmodifiableSortedSet));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Cartesian Product
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
public EclipseCollectionsDeckOfCards() {
this.cards = SortedSets.immutable.with(
Card.streamCards()
.toArray(Card[]::new));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Cartesian Product
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
public GoogleGuavaDeckOfCards() {
this.cards = Card.streamCards()
.collect(ImmutableSortedSet
.toImmutableSortedSet(
Comparator.naturalOrder()));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Cartesian Product
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
public JavaSlangDeckOfCards() {
this.cards = Card.streamCards()
.collect(TreeSet.collector());
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test - groupBy
540,396
183,848
231,321
176,412
353,651
-
100,000
200,000
300,000
400,000
500,000
600,000
Scoreops/s
Framework
groupBy
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Group By
public class JDK8DeckOfCards {
private Map<Suit, SortedSet<Card>> cardsBySuit;
public JDK8DeckOfCards() {
this.cardsBySuit =
Collections.unmodifiableMap(
this.cards.stream()
.collect(Collectors.groupingBy(
Card::getSuit,
Collectors.mapping(
Function.identity(),
Collectors.collectingAndThen(
Collectors.toCollection(TreeSet::new),
Collections::unmodifiableSortedSet)))));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Group By
public class ApacheCommonsDeckOfCards {
private MultiValuedMap<Suit, Card> cardsBySuit;
public ApacheCommonsDeckOfCards() {
SetValuedMap<Suit, Card> cbs =
MultiMapUtils.newSetValuedHashMap();
this.cards.forEach(card ->
cbs.put(card.getSuit(), card));
this.cardsBySuit =
MultiMapUtils.unmodifiableMultiValuedMap(cbs);
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Group By
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public EclipseCollectionsDeckOfCards() {
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Group By
public class GoogleGuavaDeckOfCards {
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public GoogleGuavaDeckOfCards() {
ImmutableSetMultimap.Builder<Suit, Card> builder =
new ImmutableSetMultimap.Builder<Suit, Card>()
.orderValuesBy(Comparator.naturalOrder());
this.cards.forEach(card ->
builder.put(card.getSuit(), card));
this.cardsBySuit = builder.build();
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Group By
public class JavaSlangDeckOfCards {
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
public JavaSlangDeckOfCards() {
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Deck of Cards
102,037
79,343 76,982
56,224
91,017
0
20,000
40,000
60,000
80,000
100,000
120,000
Scoreops/s
Framework
Deck of Cards
Apache EC Guava Javaslang JDK
540,396
183,848231,321176,412
353,651
-
500,000
1,000,000
Scoreops/s Framework
groupBy
Apache EC Guava Javaslang JDK
185,087 203,660
465,999
127,439 114,634
0
200,000
400,000
600,000
Scoreops/s
Framework
Cartesian Product
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test - countsBySuit
706,272
1,096,527
533,728
440,786
724,526
0
200,000
400,000
600,000
800,000
1,000,000
1,200,000
Scoreops/s
Framework
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test - countsByRank
539,252
827,986
444,832
390,134
591,869
0
100,000
200,000
300,000
400,000
500,000
600,000
700,000
800,000
900,000
Scoreops/s
Framework
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Count By
public Map<Suit, Long> countsBySuit() {
return this.cards.stream()
.collect(Collectors.groupingBy(
Card::getSuit, Collectors.counting()));
}
public Map<Rank, Long> countsByRank() {
return this.cards.stream()
.collect(Collectors.groupingBy(
Card::getRank, Collectors.counting()));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Count By
public Bag<Suit> countsBySuit() {
return this.cards.stream()
.map(Card::getSuit)
.collect(Collectors.toCollection(HashBag::new));
}
public MultiSet<Rank> countsByRank() {
return this.cards.stream()
.map(Card::getRank)
.collect(Collectors.toCollection(
HashMultiSet::new));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Count By
public Bag<Suit> countsBySuit() {
return this.cards.asLazy()
.collect(Card::getSuit)
.toBag();
}
public Bag<Rank> countsByRank() {
return this.cards.asLazy()
.collect(Card::getRank)
.toBag();
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Count By
public Multiset<Suit> countsBySuit() {
return this.cards.stream()
.map(Card::getSuit)
.collect(Collectors.toCollection(
HashMultiset::create));
}
public Multiset<Rank> countsByRank() {
return this.cards.stream()
.map(Card::getRank)
.collect(Collectors.toCollection(
HashMultiset::create));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Count By
public java.util.Map<Suit, Long> countsBySuit() {
return this.cards.collect(
Collectors.groupingBy(
Card::getSuit,
Collectors.counting()));
}
public java.util.Map<Rank, Long> countsByRank() {
return this.cards.collect(
Collectors.groupingBy(
Card::getRank,
Collectors.counting()));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of
five cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Deal Hands
291,488
502,448
305,673
372,466
300,975
0
100,000
200,000
300,000
400,000
500,000
600,000
Scoreops/s
Framework
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Deal Hands
public List<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand) {
return IntStream.range(0, hands)
.mapToObj(i ->
this.deal(shuffled, cardsPerHand))
.collect(
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Deal Hands
public List<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand) {
return IntStream.range(0, hands)
.mapToObj(i ->
this.deal(shuffled, cardsPerHand))
.collect(
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Deal Hands
public ImmutableList<Set<Card>> dealHands(
MutableStack<Card> shuffled,
int hands,
int cardsPerHand) {
return IntInterval.oneTo(hands)
.collect(i ->
this.deal(shuffled, cardsPerHand));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Deal Hands
public ImmutableList<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand) {
return IntStream.range(0, hands)
.mapToObj(i ->
this.deal(shuffled, cardsPerHand))
.collect(ImmutableList.toImmutableList());
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Deal Hands
public List<Set<Card>> dealHands(
Stack<Card> shuffled,
int hands,
int cardsPerHand) {
List<Set<Card>> list = List.empty();
for (int i = 0; i < hands; i++) {
Tuple2<Set<Card>, ? extends Stack<Card>> tuple2 =
this.deal(shuffled, cardsPerHand);
shuffled = tuple2._2();
list = list.append(tuple2._1());
}
return list;
}
Memory Benchmarks
#CollectionsCompare #GIDS17 @NikhilNanivade
Memory Benchmarks
• ObjectExplorer, by Dimitris Andrew
• Open Source under Apache License 2.0
• Measure Reported –
– Memory (Kb) vs Size
– Memory (Kb) vs List, Set, Map with 1,000,000 elements
• Smaller the better
Sources
– GitHub:
https://github.com/DimitrisAndreou/memory-measurer
– Found from StackOverflow:
http://stackoverflow.com/a/9368930/5182052
#CollectionsCompare #GIDS17 @NikhilNanivade
List<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
List<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
List<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
List<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<Integer, Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<Integer, Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<String, String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<String, String>
Summary
#CollectionsCompare #GIDS17 @NikhilNanivade
Link
• The Collections Compare Project
https://github.com/nikhilnanivadekar/CollectionsCompare
#CollectionsCompare #GIDS17 @NikhilNanivade
Collection Framework Comparison
Feature JDK Apache Guava Eclipse Javaslang 1st, 2nd, 3rd
List, Set, Map ✔  ✖ ✔  JDK, EC, JS
Multiset / Bag ✖ ✔ ✔ ✔ ✖ GG, EC, AC
Multimap ✖ ✔ ✔ ✔ ✔ GG, EC, AC
BiMap ✖ ✔ ✔ ✔ ✖ GG, EC, AC
Stack ✔  ✖ ✔ ✔ EC, JDK, JS
Tree / Trie ✖ ✔ ✖ ✖ ✔ JS, AC
Table ✖ ✖ ✔ ✖ ✖ GG
Additional Types ✔ ✔ ✔   AC, JDK, GG
Immutable? ✖ ✖ ✔ ✔ ✔ JS, EC, GG
Primitives?  ✖  ✔ ✖ EC, JDK, GG
Fluent API    ✔ ✔ EC, JS, JDK
(E), (L), (S), (P)* , ✔, ✔, ✔ , , ✔, ✖ ✖, , ✔, ✖ ✔, ✔, ✔, ✔ ✔, ✔, ✔, ✖ EC, JDK, JS
Thanks!
The Collections Compare Project
https://github.com/nikhilnanivadekar/CollectionsCompare

Collections.compare(JDK, Eclipse, Guava, Apache...); GIDS 2017

  • 1.
    Collections.compare(() -> { JDK;Apache; Eclipse; Guava...}); Nikhil J. Nanivadekar
  • 2.
    #CollectionsCompare #GIDS17 @NikhilNanivade Agenda 1.Introduction 2. History of Java util collections framework 3. Gaps in use cases from the timeline 4. Timeline with other collection frameworks 5. Use case, domain diagrams 6. Deep dive in use case 7. Memory characteristics
  • 3.
    #CollectionsCompare #GIDS17 @NikhilNanivade Authors •Donald Raab (@TheDonRaab) • Leonardo Lima (@leomrlima) • Nikhil J. Nanivadekar (@NikhilNanivade)
  • 4.
    #CollectionsCompare #GIDS17 @NikhilNanivade Speaker NikhilJ. Nanivadekar – Mechanical Engineer – Software developer – Vice President, Technology at Goldman Sachs – From Pune, Maharashtra currently in Salt Lake City, Utah
  • 5.
  • 6.
    #CollectionsCompare #GIDS17 @NikhilNanivade java.utilCollections • Java Collection Framework has been around since 1998/JDK 1.2. Very basic but critical collection support for Java. • Interfaces: Maps and Collections (List, Set, Queue, Deque) • Implementations: Basic and Concurrent versions of the interfaces, sorted and concurrent as well • Algorithms: Sorting, Shuffling, Routine Data Manipulation, Searching, Composition • Best way to get started is using the simple and concurrent tutorials
  • 7.
    #CollectionsCompare #GIDS17 @NikhilNanivade JavaCollections Frameworks Java 2 1998 • Interfaces • Collection • List • Set • Map • SortedSet • SortedMap Java 5 2005 • Generics • For-each loop • Interfaces • Iterable • Queue • ConcurrentMap • BlockingQueue Java 6 2006 •Interfaces •NavigableSet •NavigableMap •Deque •BlockingDeque •ConcurrentNavigableMap Java 7 2011 • Interfaces • TransferQueue Java 8 2014 • Lambdas • Method Refs • Default Methods • Interfaces • BaseStream • Stream • IntStream • LongStream • DoubleStream • Collector • Spliterator • PrimitiveIterator
  • 8.
  • 9.
    #CollectionsCompare #GIDS17 @NikhilNanivade !java.utilCollections • We’re considering 4 collection frameworks, in alphabetical order: • Apache Commons Collection – version 4.1 • Eclipse Collections (Formerly GS Collections) – version 8.1.0 • Google Guava – version 21.0 • Javaslang (now called Vavr) – version 2.1.0-alpha
  • 10.
    #CollectionsCompare #GIDS17 @NikhilNanivade CollectionFramework Timelines Java 2 1998 •Jakarta Collections 1.0 •2001 •Apache Collections 3.0 •2004 Java 6 2006 •Google Collections 1.0 •Dec. 2009 Java 7 2011 •Google Guava 10.0 •Sept. 2011 •GS Collections 1.0 •Jan. 2012 •Apache Collections 4.0 •Nov. 2013 Java 8 2014 •Javaslang 1.0 •Mar. 2014 •Apache Collections 4.1 •Nov. 2015 •Eclipse Collections 7.0 •Jan. 2016 •Eclipse Collections 8.0 (Java 8) •Sept. 2016 •Google Guava 20.0 •Oct. 2016 •Javaslang 2.1a •Nov. 2016 March 2017 •Google Guava 21.0 (Java 8) •Jan. 2017 •Eclipse Collections 8.1 •Mar. 2017
  • 11.
  • 12.
    #CollectionsCompare #GIDS17 @NikhilNanivade UseCase – Deck of Cards The Collections Compare Project: https://github.com/nikhilnanivadekar/CollectionsCompare
  • 13.
    #CollectionsCompare #GIDS17 @NikhilNanivade ProblemStatement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 14.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceBenchmarks • JMH – Java Microbenchmark Harness • http://openjdk.java.net/projects/code-tools/jmh/ • Measure Reported – Operations per second • Bigger numbers are better • 4 Core Intel I7, 50 Warm-up iterations, 30 measurement iterations, two forks
  • 15.
    #CollectionsCompare #GIDS17 @NikhilNanivade ProblemStatement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 16.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest – Deck of Cards 102,037 79,343 76,982 56,224 91,017 0 20,000 40,000 60,000 80,000 100,000 120,000 Scoreops/s Framework Deck of Cards Apache EC Guava Javaslang JDK
  • 17.
    #CollectionsCompare #GIDS17 @NikhilNanivade ADeck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 18.
    #CollectionsCompare #GIDS17 @NikhilNanivade ADeck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 19.
    #CollectionsCompare #GIDS17 @NikhilNanivade ADeck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 20.
    #CollectionsCompare #GIDS17 @NikhilNanivade ADeck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 21.
    #CollectionsCompare #GIDS17 @NikhilNanivade ADeck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 22.
    #CollectionsCompare #GIDS17 @NikhilNanivade ADeck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 23.
    #CollectionsCompare #GIDS17 @NikhilNanivade ProblemStatement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 24.
    #CollectionsCompare #GIDS17 @NikhilNanivade SharedCode – Cartesian Product public static Stream<Card> streamCards() { return Card.cartesianProduct( EnumSet.allOf(Rank.class), EnumSet.allOf(Suit.class), Card::new); } private static <A, B, C> Stream<C> cartesianProduct( Set<A> set1, Set<B> set2, Function2<A, B, C> function) { return set1.stream().flatMap(first -> set2.stream().map(second -> function.apply(first, second))); }
  • 25.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest – Cartesian Product 185,087 203,660 465,999 127,439 114,634 0 50,000 100,000 150,000 200,000 250,000 300,000 350,000 400,000 450,000 500,000 Scoreops/s Framework Cartesian Product Apache EC Guava Javaslang JDK
  • 26.
    #CollectionsCompare #GIDS17 @NikhilNanivade JDKCollections – Cartesian Product public class JDK8DeckOfCards { private SortedSet<Card> cards; public JDK8DeckOfCards() { this.cards = Card.streamCards() .collect(Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), Collections::unmodifiableSortedSet)); }
  • 27.
    #CollectionsCompare #GIDS17 @NikhilNanivade ApacheCollections – Cartesian Product public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; public ApacheCommonsDeckOfCards() { this.cards = Card.streamCards() .collect(Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), Collections::unmodifiableSortedSet)); }
  • 28.
    #CollectionsCompare #GIDS17 @NikhilNanivade EclipseCollections – Cartesian Product public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; public EclipseCollectionsDeckOfCards() { this.cards = SortedSets.immutable.with( Card.streamCards() .toArray(Card[]::new)); }
  • 29.
    #CollectionsCompare #GIDS17 @NikhilNanivade GoogleGuava – Cartesian Product public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; public GoogleGuavaDeckOfCards() { this.cards = Card.streamCards() .collect(ImmutableSortedSet .toImmutableSortedSet( Comparator.naturalOrder())); }
  • 30.
    #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang– Cartesian Product public class JavaSlangDeckOfCards { private SortedSet<Card> cards; public JavaSlangDeckOfCards() { this.cards = Card.streamCards() .collect(TreeSet.collector()); }
  • 31.
    #CollectionsCompare #GIDS17 @NikhilNanivade ProblemStatement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 32.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest - groupBy 540,396 183,848 231,321 176,412 353,651 - 100,000 200,000 300,000 400,000 500,000 600,000 Scoreops/s Framework groupBy Apache EC Guava Javaslang JDK
  • 33.
    #CollectionsCompare #GIDS17 @NikhilNanivade JDKCollections – Group By public class JDK8DeckOfCards { private Map<Suit, SortedSet<Card>> cardsBySuit; public JDK8DeckOfCards() { this.cardsBySuit = Collections.unmodifiableMap( this.cards.stream() .collect(Collectors.groupingBy( Card::getSuit, Collectors.mapping( Function.identity(), Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), Collections::unmodifiableSortedSet))))); }
  • 34.
    #CollectionsCompare #GIDS17 @NikhilNanivade ApacheCollections – Group By public class ApacheCommonsDeckOfCards { private MultiValuedMap<Suit, Card> cardsBySuit; public ApacheCommonsDeckOfCards() { SetValuedMap<Suit, Card> cbs = MultiMapUtils.newSetValuedHashMap(); this.cards.forEach(card -> cbs.put(card.getSuit(), card)); this.cardsBySuit = MultiMapUtils.unmodifiableMultiValuedMap(cbs); }
  • 35.
    #CollectionsCompare #GIDS17 @NikhilNanivade EclipseCollections – Group By public class EclipseCollectionsDeckOfCards { private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public EclipseCollectionsDeckOfCards() { this.cardsBySuit = this.cards.groupBy(Card::getSuit); }
  • 36.
    #CollectionsCompare #GIDS17 @NikhilNanivade GoogleGuava – Group By public class GoogleGuavaDeckOfCards { private ImmutableSetMultimap<Suit, Card> cardsBySuit; public GoogleGuavaDeckOfCards() { ImmutableSetMultimap.Builder<Suit, Card> builder = new ImmutableSetMultimap.Builder<Suit, Card>() .orderValuesBy(Comparator.naturalOrder()); this.cards.forEach(card -> builder.put(card.getSuit(), card)); this.cardsBySuit = builder.build(); }
  • 37.
    #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang– Group By public class JavaSlangDeckOfCards { private Map<Suit, ? extends SortedSet<Card>> cardsBySuit; public JavaSlangDeckOfCards() { this.cardsBySuit = this.cards.groupBy(Card::getSuit); }
  • 38.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest – Deck of Cards 102,037 79,343 76,982 56,224 91,017 0 20,000 40,000 60,000 80,000 100,000 120,000 Scoreops/s Framework Deck of Cards Apache EC Guava Javaslang JDK 540,396 183,848231,321176,412 353,651 - 500,000 1,000,000 Scoreops/s Framework groupBy Apache EC Guava Javaslang JDK 185,087 203,660 465,999 127,439 114,634 0 200,000 400,000 600,000 Scoreops/s Framework Cartesian Product Apache EC Guava Javaslang JDK
  • 39.
    #CollectionsCompare #GIDS17 @NikhilNanivade ProblemStatement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 40.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest - countsBySuit 706,272 1,096,527 533,728 440,786 724,526 0 200,000 400,000 600,000 800,000 1,000,000 1,200,000 Scoreops/s Framework Apache EC Guava Javaslang JDK
  • 41.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest - countsByRank 539,252 827,986 444,832 390,134 591,869 0 100,000 200,000 300,000 400,000 500,000 600,000 700,000 800,000 900,000 Scoreops/s Framework Apache EC Guava Javaslang JDK
  • 42.
    #CollectionsCompare #GIDS17 @NikhilNanivade JDKCollections – Count By public Map<Suit, Long> countsBySuit() { return this.cards.stream() .collect(Collectors.groupingBy( Card::getSuit, Collectors.counting())); } public Map<Rank, Long> countsByRank() { return this.cards.stream() .collect(Collectors.groupingBy( Card::getRank, Collectors.counting())); }
  • 43.
    #CollectionsCompare #GIDS17 @NikhilNanivade ApacheCollections – Count By public Bag<Suit> countsBySuit() { return this.cards.stream() .map(Card::getSuit) .collect(Collectors.toCollection(HashBag::new)); } public MultiSet<Rank> countsByRank() { return this.cards.stream() .map(Card::getRank) .collect(Collectors.toCollection( HashMultiSet::new)); }
  • 44.
    #CollectionsCompare #GIDS17 @NikhilNanivade EclipseCollections – Count By public Bag<Suit> countsBySuit() { return this.cards.asLazy() .collect(Card::getSuit) .toBag(); } public Bag<Rank> countsByRank() { return this.cards.asLazy() .collect(Card::getRank) .toBag(); }
  • 45.
    #CollectionsCompare #GIDS17 @NikhilNanivade GoogleGuava – Count By public Multiset<Suit> countsBySuit() { return this.cards.stream() .map(Card::getSuit) .collect(Collectors.toCollection( HashMultiset::create)); } public Multiset<Rank> countsByRank() { return this.cards.stream() .map(Card::getRank) .collect(Collectors.toCollection( HashMultiset::create)); }
  • 46.
    #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang– Count By public java.util.Map<Suit, Long> countsBySuit() { return this.cards.collect( Collectors.groupingBy( Card::getSuit, Collectors.counting())); } public java.util.Map<Rank, Long> countsByRank() { return this.cards.collect( Collectors.groupingBy( Card::getRank, Collectors.counting())); }
  • 47.
    #CollectionsCompare #GIDS17 @NikhilNanivade ProblemStatement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 48.
    #CollectionsCompare #GIDS17 @NikhilNanivade PerformanceTest – Deal Hands 291,488 502,448 305,673 372,466 300,975 0 100,000 200,000 300,000 400,000 500,000 600,000 Scoreops/s Framework Apache EC Guava Javaslang JDK
  • 49.
    #CollectionsCompare #GIDS17 @NikhilNanivade JDKCollections – Deal Hands public List<Set<Card>> dealHands( Deque<Card> shuffled, int hands, int cardsPerHand) { return IntStream.range(0, hands) .mapToObj(i -> this.deal(shuffled, cardsPerHand)) .collect( Collectors.collectingAndThen( Collectors.toList(), Collections::unmodifiableList)); }
  • 50.
    #CollectionsCompare #GIDS17 @NikhilNanivade ApacheCollections – Deal Hands public List<Set<Card>> dealHands( Deque<Card> shuffled, int hands, int cardsPerHand) { return IntStream.range(0, hands) .mapToObj(i -> this.deal(shuffled, cardsPerHand)) .collect( Collectors.collectingAndThen( Collectors.toList(), Collections::unmodifiableList)); }
  • 51.
    #CollectionsCompare #GIDS17 @NikhilNanivade EclipseCollections – Deal Hands public ImmutableList<Set<Card>> dealHands( MutableStack<Card> shuffled, int hands, int cardsPerHand) { return IntInterval.oneTo(hands) .collect(i -> this.deal(shuffled, cardsPerHand)); }
  • 52.
    #CollectionsCompare #GIDS17 @NikhilNanivade GoogleGuava – Deal Hands public ImmutableList<Set<Card>> dealHands( Deque<Card> shuffled, int hands, int cardsPerHand) { return IntStream.range(0, hands) .mapToObj(i -> this.deal(shuffled, cardsPerHand)) .collect(ImmutableList.toImmutableList()); }
  • 53.
    #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang– Deal Hands public List<Set<Card>> dealHands( Stack<Card> shuffled, int hands, int cardsPerHand) { List<Set<Card>> list = List.empty(); for (int i = 0; i < hands; i++) { Tuple2<Set<Card>, ? extends Stack<Card>> tuple2 = this.deal(shuffled, cardsPerHand); shuffled = tuple2._2(); list = list.append(tuple2._1()); } return list; }
  • 54.
  • 55.
    #CollectionsCompare #GIDS17 @NikhilNanivade MemoryBenchmarks • ObjectExplorer, by Dimitris Andrew • Open Source under Apache License 2.0 • Measure Reported – – Memory (Kb) vs Size – Memory (Kb) vs List, Set, Map with 1,000,000 elements • Smaller the better Sources – GitHub: https://github.com/DimitrisAndreou/memory-measurer – Found from StackOverflow: http://stackoverflow.com/a/9368930/5182052
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
    #CollectionsCompare #GIDS17 @NikhilNanivade Link •The Collections Compare Project https://github.com/nikhilnanivadekar/CollectionsCompare
  • 70.
    #CollectionsCompare #GIDS17 @NikhilNanivade CollectionFramework Comparison Feature JDK Apache Guava Eclipse Javaslang 1st, 2nd, 3rd List, Set, Map ✔  ✖ ✔  JDK, EC, JS Multiset / Bag ✖ ✔ ✔ ✔ ✖ GG, EC, AC Multimap ✖ ✔ ✔ ✔ ✔ GG, EC, AC BiMap ✖ ✔ ✔ ✔ ✖ GG, EC, AC Stack ✔  ✖ ✔ ✔ EC, JDK, JS Tree / Trie ✖ ✔ ✖ ✖ ✔ JS, AC Table ✖ ✖ ✔ ✖ ✖ GG Additional Types ✔ ✔ ✔   AC, JDK, GG Immutable? ✖ ✖ ✔ ✔ ✔ JS, EC, GG Primitives?  ✖  ✔ ✖ EC, JDK, GG Fluent API    ✔ ✔ EC, JS, JDK (E), (L), (S), (P)* , ✔, ✔, ✔ , , ✔, ✖ ✖, , ✔, ✖ ✔, ✔, ✔, ✔ ✔, ✔, ✔, ✖ EC, JDK, JS
  • 71.
    Thanks! The Collections CompareProject https://github.com/nikhilnanivadekar/CollectionsCompare