/* * Quasar: lightweight threads and actors for the JVM. * Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 3.0 * as published by the Free Software Foundation. */ package co.paralleluniverse.strands.queues; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedTransferQueue; import org.openjdk.jmh.Main; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Group; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.infra.Control; /** * * @author Martin Thompson * @autor pron */ public class QueueJMHBenchmark { /* * See: * http://psy-lob-saw.blogspot.co.il/2013/04/writing-java-micro-benchmarks-with-jmh.html * http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/ */ private static final String BENCHMARK = QueueJMHBenchmark.class.getName() + ".*"; public static void main(String[] args) throws Exception { // Main.main(new String[]{"-usage"}); Main.main(buildArguments(BENCHMARK, 5, 5000, 3)); } private static String[] buildArguments(String className, int nRuns, int runForMilliseconds, int nProducers) { return new String[]{className, "-f", "1", "-i", "" + nRuns, "-r", runForMilliseconds + "ms", "-tg", "1," + nProducers, "-w", "5000ms", "-wi", "3",}; } private static final int QUEUE_CAPACITY = 32 * 1024; private static final Integer TEST_VALUE = Integer.valueOf(777); @State(Scope.Group) public static class Q { Queue<Integer> singleConsumerArrayObjectQueue = new SingleConsumerArrayObjectQueue<Integer>(QUEUE_CAPACITY); Queue<Integer> singleConsumerArrayIntQueue = new SingleConsumerArrayIntQueue(QUEUE_CAPACITY); Queue<Integer> singleConsumerLinkedObjectQueue = new SingleConsumerLinkedObjectQueue<Integer>(); Queue<Integer> singleConsumerLinkedIntQueue = new SingleConsumerLinkedIntQueue(); Queue<Integer> singleConsumerLinkedArrayObjectQueue = new SingleConsumerLinkedArrayObjectQueue<Integer>(); Queue<Integer> singleConsumerLinkedArrayIntQueue = new SingleConsumerLinkedArrayIntQueue(); Queue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<Integer>(QUEUE_CAPACITY); Queue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<Integer>(QUEUE_CAPACITY); Queue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<Integer>(); Queue<Integer> linkedTransferQueue = new LinkedTransferQueue<Integer>(); } public void write(Control cnt, Queue<Integer> queue) { while (!cnt.stopMeasurement && !queue.offer(TEST_VALUE)) Thread.yield(); } public Integer read(Control cnt, Queue<Integer> queue) { Integer result = null; while (!cnt.stopMeasurement && null == (result = queue.poll())) Thread.yield(); return result; } // it is important that "read" is lexicographically lower than "write", as this is the order specified in the -tg flag @Benchmark @Group("singleConsumerArrayObjectQueue") public Object read_singleConsumerArrayObjectQueue(Control cnt, Q q) { return read(cnt, q.singleConsumerArrayObjectQueue); } @Benchmark @Group("singleConsumerArrayObjectQueue") public void write_singleConsumerArrayObjectQueue(Control cnt, Q q) { write(cnt, q.singleConsumerArrayObjectQueue); } @Benchmark @Group("singleConsumerLinkedObjectQueue") public Object read_SingleConsumerLinkedObjectQueue(Control cnt, Q q) { return read(cnt, q.singleConsumerLinkedObjectQueue); } @Benchmark @Group("singleConsumerLinkedObjectQueue") public void write_SingleConsumerLinkedObjectQueue(Control cnt, Q q) { write(cnt, q.singleConsumerLinkedObjectQueue); } @Benchmark @Group("singleConsumerLinkedArrayObjectQueue") public Object read_SingleConsumerLinkedArrayObjectQueue(Control cnt, Q q) { return read(cnt, q.singleConsumerLinkedArrayObjectQueue); } @Benchmark @Group("singleConsumerLinkedArrayObjectQueue") public void write_SingleConsumerLinkedArrayObjectQueue(Control cnt, Q q) { write(cnt, q.singleConsumerLinkedArrayObjectQueue); } @Benchmark @Group("singleConsumerArrayIntQueue") public Object read_SingleConsumerArrayIntQueue(Control cnt, Q q) { return read(cnt, q.singleConsumerArrayIntQueue); } @Benchmark @Group("singleConsumerArrayIntQueue") public void write_SingleConsumerArrayIntQueue(Control cnt, Q q) { write(cnt, q.singleConsumerArrayIntQueue); } @Benchmark @Group("singleConsumerLinkedIntQueue") public Object read_SingleConsumerLinkedIntQueue(Control cnt, Q q) { return read(cnt, q.singleConsumerLinkedIntQueue); } @Benchmark @Group("singleConsumerLinkedIntQueue") public void write_SingleConsumerLinkedIntQueue(Control cnt, Q q) { write(cnt, q.singleConsumerLinkedIntQueue); } @Benchmark @Group("singleConsumerLinkedArrayIntQueue") public Object read_SingleConsumerLinkedArrayIntQueue(Control cnt, Q q) { return read(cnt, q.singleConsumerLinkedArrayIntQueue); } @Benchmark @Group("singleConsumerLinkedArrayIntQueue") public void write_SingleConsumerLinkedArrayIntQueue(Control cnt, Q q) { write(cnt, q.singleConsumerLinkedArrayIntQueue); } @Benchmark @Group("arrayBlockingQueue") public Object read_ArrayBlockingQueue(Control cnt, Q q) { return read(cnt, q.arrayBlockingQueue); } @Benchmark @Group("arrayBlockingQueue") public void write_ArrayBlockingQueue(Control cnt, Q q) { write(cnt, q.arrayBlockingQueue); } @Benchmark @Group("linkedBlockingQueue") public Object read_LinkedBlockingQueue(Control cnt, Q q) { return read(cnt, q.linkedBlockingQueue); } @Benchmark @Group("linkedBlockingQueue") public void write_LinkedBlockingQueue(Control cnt, Q q) { write(cnt, q.linkedBlockingQueue); } @Benchmark @Group("concurrentLinkedQueue") public Object read_ConcurrentLinkedQueue(Control cnt, Q q) { return read(cnt, q.concurrentLinkedQueue); } @Benchmark @Group("concurrentLinkedQueue") public void write_ConcurrentLinkedQueue(Control cnt, Q q) { write(cnt, q.concurrentLinkedQueue); } @Benchmark @Group("linkedTransferQueue") public Object read_LinkedTransferQueue(Control cnt, Q q) { return read(cnt, q.linkedTransferQueue); } @Benchmark @Group("linkedTransferQueue") public void write_LinkedTransferQueue(Control cnt, Q q) { write(cnt, q.linkedTransferQueue); } } // Results //Benchmark Mode Samples Score Error Units //c.p.s.q.QueueJMHBenchmark.arrayBlockingQueue thrpt 5 23398791.242 ± 1376044.568 ops/s //c.p.s.q.QueueJMHBenchmark.concurrentLinkedQueue thrpt 5 15343361.824 ± 401694.904 ops/s //c.p.s.q.QueueJMHBenchmark.linkedBlockingQueue thrpt 5 11357839.534 ± 1430754.782 ops/s //c.p.s.q.QueueJMHBenchmark.linkedTransferQueue thrpt 5 17485561.116 ± 792770.815 ops/s //c.p.s.q.QueueJMHBenchmark.singleConsumerArrayObjectQueue thrpt 5 40558001.629 ± 1754094.068 ops/s //c.p.s.q.QueueJMHBenchmark.singleConsumerArrayIntQueue thrpt 5 32801828.287 ± 5869817.546 ops/s //c.p.s.q.QueueJMHBenchmark.singleConsumerLinkedArrayObjectQueue thrpt 5 29168006.729 ± 2451717.977 ops/s //c.p.s.q.QueueJMHBenchmark.singleConsumerLinkedArrayIntQueue thrpt 5 25361031.363 ± 1174645.608 ops/s //c.p.s.q.QueueJMHBenchmark.singleConsumerLinkedObjectQueue thrpt 5 17215038.964 ± 914374.252 ops/s //c.p.s.q.QueueJMHBenchmark.singleConsumerLinkedIntQueue thrpt 5 17077272.828 ± 315402.200 ops/s