diff --git a/understandingcollections/CountedString.java b/understandingcollections/CountedString.java index a779a2ba..1afa8874 100644 --- a/understandingcollections/CountedString.java +++ b/understandingcollections/CountedString.java @@ -14,7 +14,7 @@ public class CountedString { s = str; created.add(s); // id is the total number of instances - // of this String in use by CountedString: + // of this String used by CountedString: for(String s2 : created) if(s2.equals(s)) id++; diff --git a/understandingcollections/SuppliersCollectionTest.java b/understandingcollections/SuppliersCollectionTest.java index e9c79995..67870590 100644 --- a/understandingcollections/SuppliersCollectionTest.java +++ b/understandingcollections/SuppliersCollectionTest.java @@ -29,7 +29,7 @@ public class SuppliersCollectionTest { Suppliers.fill(list, new Government(), 15); System.out.println(list); - // Or we could just use Streams: + // Or we can use Streams: set = Arrays.stream(Government.foundation).collect( Collectors.toSet()); System.out.println(set); diff --git a/understandingcollections/ToDoList.java b/understandingcollections/ToDoList.java index 20bdeed6..44678b6e 100644 --- a/understandingcollections/ToDoList.java +++ b/understandingcollections/ToDoList.java @@ -36,15 +36,15 @@ class ToDoList extends PriorityQueue { super.add(new ToDoItem(td, pri, sec)); } public static void main(String[] args) { - ToDoList toDoList = new ToDoList(); - toDoList.add("Empty trash", 'C', 4); - toDoList.add("Feed dog", 'A', 2); - toDoList.add("Feed bird", 'B', 7); - toDoList.add("Mow lawn", 'C', 3); - toDoList.add("Water lawn", 'A', 1); - toDoList.add("Feed cat", 'B', 1); - while(!toDoList.isEmpty()) - System.out.println(toDoList.remove()); + ToDoList toDo = new ToDoList(); + toDo.add("Empty trash", 'C', 4); + toDo.add("Feed dog", 'A', 2); + toDo.add("Feed bird", 'B', 7); + toDo.add("Mow lawn", 'C', 3); + toDo.add("Water lawn", 'A', 1); + toDo.add("Feed cat", 'B', 1); + while(!toDo.isEmpty()) + System.out.println(toDo.remove()); } } /* Output: diff --git a/understandingcollections/jmh/Deques.java b/understandingcollections/jmh/Deques.java new file mode 100644 index 00000000..3f7e3386 --- /dev/null +++ b/understandingcollections/jmh/Deques.java @@ -0,0 +1,70 @@ +// understandingcollections/jmh/Deques.java +// (c)2016 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// Performance differences between Deques +package understandingcollections.jmh; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import java.util.concurrent.TimeUnit; +import java.util.*; + +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, batchSize = 5000) +@Measurement(iterations = 5, batchSize = 5000) +@BenchmarkMode(Mode.SingleShotTime) +@Fork(1) +public class Deques { + private Deque deque; + + @Param({ + "java.util.LinkedList", + "java.util.ArrayDeque", + "java.util.concurrent.ConcurrentLinkedDeque", + "java.util.concurrent.LinkedBlockingDeque", + }) + private String type; + + @Param({ + "1", + "10", + "100", + "1000", + "10000", + "100000" + }) + private int size; + + @Setup + public void setup() { + try { + deque = (Deque) + Class.forName(type).newInstance(); + } catch(Exception e) { + System.err.println( + "-> Cannot create: " + type); + System.exit(99); + } + for(int i = 0; i < size; i++) + deque.add(Integer.toString(i)); + } + @Benchmark + public Deque addFirst() { + deque.addFirst("test"); + return deque; + } + @Benchmark + public Deque addLast() { + deque.addLast("test"); + return deque; + } + @Benchmark + public void pollFirst(Blackhole bh) { + bh.consume(deque.pollFirst()); + } + @Benchmark + public void pollLast(Blackhole bh) { + bh.consume(deque.pollLast()); + } +} diff --git a/understandingcollections/jmh/Lists.java b/understandingcollections/jmh/Lists.java index 8c1b32a3..6a77df62 100644 --- a/understandingcollections/jmh/Lists.java +++ b/understandingcollections/jmh/Lists.java @@ -2,80 +2,90 @@ // (c)2016 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. -// Demonstrates performance differences in Lists +// Performance differences between Lists package understandingcollections.jmh; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import java.util.*; -import static java.util.concurrent.TimeUnit.*; +import java.util.concurrent.*; @State(Scope.Thread) -@Warmup(iterations = 5, time = 1, timeUnit = SECONDS) -@Measurement(iterations = 5, time = 1, timeUnit = SECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, batchSize = 5000) +@Measurement(iterations = 5, batchSize = 5000) +@BenchmarkMode(Mode.SingleShotTime) @Fork(1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(MICROSECONDS) public class Lists { - private List list; + private List list; - @Param({"ArrayList", "LinkedList", "Vector"}) + @Param({ + "java.util.ArrayList", + "java.util.Vector", + "java.util.LinkedList", + "java.util.concurrent.CopyOnWriteArrayList" + }) private String type; - private int begin; - private int end; + @Param({ + "1", + "10", + "100", + "1000", + "10000", + "100000" + }) + private int size; @Setup public void setup() { - switch(type) { - case "ArrayList": - list = new ArrayList<>(); - break; - case "LinkedList": - list = new LinkedList<>(); - break; - case "Vector": - list = new Vector<>(); - break; - default: - throw new IllegalStateException("Unknown " + type); - } - begin = 0; - end = 256; - for(int i = begin; i < end; i++) { - list.add(i); + try { + list = (List) + Class.forName(type).newInstance(); + } catch(Exception e) { + System.err.println( + "-> Cannot create: " + type); + System.exit(99); } + for(int i = 0; i < size; i++) + list.add(Integer.toString(i)); } @Benchmark - public void add() { - for(int i = begin; i < end; i++) - list.add(i); + public List add() { + list.add(list.size() / 2, "test"); + return list; } @Benchmark public void get(Blackhole bh) { - for(int i = begin; i < end; i++) - bh.consume(list.get(i)); + bh.consume(list.get(list.size() / 2)); } @Benchmark - public void set() { - for(int i = begin; i < end; i++) - list.set(i, 47); + public List set() { + list.set(list.size() / 2, "test"); + return list; } @Benchmark - public void iteradd() { - int half = list.size() / 2; - ListIterator it = - list.listIterator(half); - for(int i = begin; i < end; i++) - it.add(47); + public List iteradd() { + ListIterator it = + list.listIterator(list.size() / 2); + try { + it.add("test"); + } catch(UnsupportedOperationException e) { + System.err.println( + "-> Unsupported: listIterator.add() in " + + list.getClass().getSimpleName()); + } + return list; } @Benchmark - public void insert() { - for(int i = begin; i < end; i++) - list.add(5, 47); + public List insert() { + list.add(list.size() / 2, "test"); + return list; } @Benchmark - public void remove() { - while(list.size() > 5) - list.remove(5); + public List remove() { + int index = list.size() / 2; + if(index > 0) + list.remove(index); + return list; } } diff --git a/understandingcollections/jmh/Maps.java b/understandingcollections/jmh/Maps.java index 79f8d26e..d9726903 100644 --- a/understandingcollections/jmh/Maps.java +++ b/understandingcollections/jmh/Maps.java @@ -7,65 +7,60 @@ package understandingcollections.jmh; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import java.util.*; -import static java.util.concurrent.TimeUnit.*; +import java.util.concurrent.*; @State(Scope.Thread) -@Warmup(iterations = 5, time = 1, timeUnit = SECONDS) -@Measurement(iterations = 5, time = 1, timeUnit = SECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, batchSize = 5000) +@Measurement(iterations = 5, batchSize = 5000) +@BenchmarkMode(Mode.SingleShotTime) @Fork(1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(MICROSECONDS) public class Maps { - private Map map; + private Map map; - @Param({"HashMap", "TreeMap", "LinkedHashMap", - "IdentityHashMap", "WeakHashMap", "Hashtable",}) + @Param({ + "java.util.HashMap", + "java.util.Hashtable", + "java.util.TreeMap", + "java.util.LinkedHashMap", + "java.util.IdentityHashMap", + "java.util.WeakHashMap", + "java.util.concurrent.ConcurrentHashMap", + "java.util.concurrent.ConcurrentSkipListMap", + }) private String type; - private int begin; - private int end; + @Param({ + "1", + "10", + "100", + "1000", + "10000", + }) + private int size; @Setup public void setup() { - switch(type) { - case "HashMap": - map = new HashMap<>(); - break; - case "TreeMap": - map = new TreeMap<>(); - break; - case "LinkedHashMap": - map = new LinkedHashMap<>(); - break; - case "IdentityHashMap": - map = new IdentityHashMap<>(); - break; - case "WeakHashMap": - map = new WeakHashMap<>(); - break; - case "Hashtable": - map = new Hashtable<>(); - break; - default: - throw new IllegalStateException("Unknown " + type); - } - begin = 1; - end = 256; - for (int i = begin; i < end; i++) { - map.put(i, i); + try { + map = (Map) + Class.forName(type).newInstance(); + } catch(Exception e) { + System.err.println( + "-> Cannot create: " + type); + System.exit(99); } + for(int i = 0; i < size; i++) + map.put(Integer.toString(i), Integer.toString(i)); } @Benchmark public void get(Blackhole bh) { - for (int i = begin; i < end; i++) { - bh.consume(map.get(i)); - } + String key = Integer.toString(size / 2); + bh.consume(map.get(key)); } @Benchmark - public void put() { - for (int i = begin; i < end; i++) { - map.put(i, i); - } + public Map put() { + map.put("test", "test"); + return map; } @Benchmark public void iterate(Blackhole bh) { diff --git a/understandingcollections/jmh/Queues.java b/understandingcollections/jmh/Queues.java index 704686c4..efcdc481 100644 --- a/understandingcollections/jmh/Queues.java +++ b/understandingcollections/jmh/Queues.java @@ -2,61 +2,68 @@ // (c)2016 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. -// Demonstrates performance differences in Queues +// Performance differences between Queues package understandingcollections.jmh; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import java.util.*; -import static java.util.concurrent.TimeUnit.*; +import java.util.concurrent.*; @State(Scope.Thread) -@Warmup(iterations = 5, time = 1, timeUnit = SECONDS) -@Measurement(iterations = 5, time = 1, timeUnit = SECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, batchSize = 5000) +@Measurement(iterations = 5, batchSize = 5000) +@BenchmarkMode(Mode.SingleShotTime) @Fork(1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(MICROSECONDS) public class Queues { - private LinkedList queue; + private Queue queue; - @Param({"LinkedList"}) + @Param({ + "java.util.LinkedList", + "java.util.concurrent.ConcurrentLinkedQueue", + "java.util.concurrent.LinkedBlockingQueue", + "java.util.concurrent.LinkedTransferQueue", + "java.util.concurrent.PriorityBlockingQueue", + "java.util.PriorityQueue", + // Requires a size for construction: + //"java.util.concurrent.ArrayBlockingQueue", + // Won't accept more than one element: + //"java.util.concurrent.SynchronousQueue", + // Requires "Delayed" elements: + //"java.util.concurrent.DelayQueue", + }) private String type; - private int begin; - private int end; + @Param({ + "1", + "10", + "100", + "1000", + "10000", + "100000" + }) + private int size; @Setup public void setup() { - switch(type) { - case "LinkedList": - queue = new LinkedList<>(); - break; - default: - throw new IllegalStateException("Unknown " + type); - } - begin = 1; - end = 256; - for(int i = begin; i < end; i++) { - queue.add(i); + try { + queue = (Queue) + Class.forName(type).newInstance(); + } catch(Exception e) { + System.err.println( + "-> Cannot create: " + type); + System.exit(99); } + for(int i = 0; i < size; i++) + queue.add(Integer.toString(i)); } @Benchmark - public void queue_addFirst() { - for(int i = begin; i < end; i++) - queue.addFirst(47); + public Queue add() { + queue.add("test"); + return queue; } @Benchmark - public void queue_addLast() { - for(int i = begin; i < end; i++) - queue.addLast(47); - } - @Benchmark - public void queue_removeFirst(Blackhole bh) { - while(queue.size() > 0) - bh.consume(queue.removeFirst()); - } - @Benchmark - public void queue_removeLast(Blackhole bh) { - while(queue.size() > 0) - bh.consume(queue.removeLast()); + public void poll(Blackhole bh) { + bh.consume(queue.poll()); } } diff --git a/understandingcollections/jmh/Sets.java b/understandingcollections/jmh/Sets.java index f45e34b7..a675b23c 100644 --- a/understandingcollections/jmh/Sets.java +++ b/understandingcollections/jmh/Sets.java @@ -7,56 +7,61 @@ package understandingcollections.jmh; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import java.util.*; -import static java.util.concurrent.TimeUnit.*; +import java.util.concurrent.*; @State(Scope.Thread) -@Warmup(iterations = 5, time = 1, timeUnit = SECONDS) -@Measurement(iterations = 5, time = 1, timeUnit = SECONDS) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 5, batchSize = 5000) +@Measurement(iterations = 5, batchSize = 5000) +@BenchmarkMode(Mode.SingleShotTime) @Fork(1) -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(MICROSECONDS) public class Sets { - private Set set; + private Set set; - @Param({"HashSet", "TreeSet", "LinkedHashSet"}) + @Param({ + "java.util.HashSet", + "java.util.TreeSet", + "java.util.LinkedHashSet", + "java.util.concurrent.ConcurrentSkipListSet", + "java.util.concurrent.CopyOnWriteArraySet", + }) private String type; - private int begin; - private int end; + @Param({ + "1", + "10", + "100", + "1000", + "10000", + }) + private int size; @Setup public void setup() { - switch(type) { - case "HashSet": - set = new HashSet<>(); - break; - case "TreeSet": - set = new TreeSet<>(); - break; - case "LinkedHashSet": - set = new LinkedHashSet<>(); - break; - default: - throw new IllegalStateException("Unknown " + type); + try { + set = (Set) + Class.forName(type).newInstance(); + } catch(Exception e) { + System.err.println( + "-> Cannot create: " + type); + System.exit(99); } - begin = 1; - end = 256; - for (int i = begin; i < end; i++) - set.add(i); + for(int i = 0; i < size; i++) + set.add(Integer.toString(i)); } @Benchmark - public void add() { - for(int i = begin; i < end; i++) - set.add(i); + public Set add() { + set.add("test"); + return set; } @Benchmark public void contains(Blackhole bh) { - for(int i = begin; i < end; i++) - bh.consume(set.contains(i)); + String key = Integer.toString(size/2); + bh.consume(set.contains(key)); } @Benchmark public void iterate(Blackhole bh) { - Iterator it = set.iterator(); + Iterator it = set.iterator(); while(it.hasNext()) bh.consume(it.next()); } diff --git a/validating/jmh/JMH3.java b/validating/jmh/JMH3.java index d4b863c5..58471bcc 100644 --- a/validating/jmh/JMH3.java +++ b/validating/jmh/JMH3.java @@ -34,8 +34,8 @@ public class JMH3 { la = new long[size]; } public static long f(long x) { - long divisor = x % 25 + 1; - return Long.divideUnsigned(x, divisor); + long quadratic = 42 * x * x + 19 * x + 47; + return Long.divideUnsigned(quadratic, x + 1); } @Benchmark public void setAll() {