MessageBus/test/dorkbox/util/messagebus/PerfTest_Collections.java

231 lines
7.3 KiB
Java

package dorkbox.util.messagebus;
import dorkbox.util.messagebus.annotations.Handler;
import dorkbox.util.messagebus.common.MessageHandler;
import dorkbox.util.messagebus.common.StrongConcurrentSet;
import dorkbox.util.messagebus.common.StrongConcurrentSetV8;
import dorkbox.util.messagebus.common.thread.ConcurrentLinkedQueue2;
import dorkbox.util.messagebus.common.thread.ConcurrentSet;
import dorkbox.util.messagebus.subscription.Subscription;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedTransferQueue;
public
class PerfTest_Collections {
public static final int REPETITIONS = 10 * 1000 * 100;
public static final Integer TEST_VALUE = Integer.valueOf(777);
private static final float LOAD_FACTOR = 0.8F;
private static final MessageHandler[] allHandlers = MessageHandler.get(Listener.class);
public static
void main(final String[] args) throws Exception {
final int size = 16;
System.out.println("reps:" + REPETITIONS + " size: " + size);
// have to warm-up the JVM.
System.err.print("\nWarming up JVM.");
// for (int i=0;i<2;i++) {
bench(size, new ConcurrentLinkedQueue<Subscription>(), false);
System.err.print(".");
bench(size, new ArrayList<Subscription>(size * 2), false);
System.err.print(".");
bench(size, new ArrayDeque<Subscription>(size * 2), false);
System.err.print(".");
bench(size, new ConcurrentLinkedQueue<Subscription>(), false);
System.err.print(".");
bench(size, new LinkedList<Subscription>(), false);
System.err.print(".");
// }
System.err.println("Done");
bench(size, new ArrayList<Subscription>(size * 2));
bench(size, new ConcurrentSet<Subscription>(size * 2, LOAD_FACTOR, 5));
bench(size, new ConcurrentLinkedQueue2<Subscription>());
bench(size, new ConcurrentLinkedQueue<Subscription>());
bench(size, new LinkedTransferQueue<Subscription>());
bench(size, new ArrayDeque<Subscription>(size * 2));
bench(size, new LinkedList<Subscription>());
bench(size, new StrongConcurrentSetV8<Subscription>(size * 2, LOAD_FACTOR));
bench(size, new StrongConcurrentSet<Subscription>(size * 2, LOAD_FACTOR));
bench(size, Collections.newSetFromMap(new ConcurrentHashMap<Subscription, Boolean>(size * 2, LOAD_FACTOR, 1)));
bench(size, new HashSet<Subscription>());
// bench(size, new ConcurrentSkipListSet<Subscription>()); // needs comparable
}
public static
void bench(final int size, Collection<Subscription> set) throws Exception {
bench(size, set, true);
}
public static
void bench(final int size, Collection<Subscription> set, boolean showOutput) throws Exception {
final int warmupRuns = 2;
final int runs = 3;
for (int i = 0; i < size; i++) {
for (MessageHandler x : allHandlers) {
set.add(new Subscription(x, .85F, 1));
}
}
if (!showOutput) {
for (int i = 2; i < 6; i++) {
averageRun(warmupRuns, runs, set, false, i, REPETITIONS);
}
}
else {
for (int i = 1; i < 10; i++) {
long average = averageRun(warmupRuns, runs, set, false, i, REPETITIONS);
System.out.format("summary,IteratorPerfTest,%s - %,d (%d)\n", set.getClass().getSimpleName(), average, i);
}
}
set.clear();
}
public static
long averageRun(int warmUpRuns, int sumCount, Collection<Subscription> set, boolean showStats, int concurrency, int repetitions)
throws Exception {
int runs = warmUpRuns + sumCount;
final long[] results = new long[runs];
for (int i = 0; i < runs; i++) {
WeakReference<Object> weakReference = new WeakReference<Object>(new Object());
while (weakReference.get() != null) {
System.gc();
Thread.sleep(100L);
}
results[i] = performanceRun(i, set, showStats, concurrency, repetitions);
}
// only average last X results for summary
long sum = 0;
for (int i = warmUpRuns; i < runs; i++) {
sum += results[i];
}
return sum / sumCount;
}
private static
long performanceRun(int runNumber, Collection<Subscription> set, boolean showStats, int concurrency, int repetitions) throws Exception {
Producer[] producers = new Producer[concurrency];
Thread[] threads = new Thread[concurrency * 2];
for (int i = 0; i < concurrency; i++) {
producers[i] = new Producer(set, repetitions);
threads[i] = new Thread(producers[i], "Producer " + i);
}
for (int i = 0; i < concurrency; i++) {
threads[i].start();
}
for (int i = 0; i < concurrency; i++) {
threads[i].join();
}
long start = Long.MAX_VALUE;
long end = -1;
long count = 0;
for (int i = 0; i < concurrency; i++) {
if (producers[i].start < start) {
start = producers[i].start;
}
if (producers[i].end > end) {
end = producers[i].end;
}
count += producers[i].count;
}
long duration = end - start;
long ops = repetitions * 1000000000L / duration;
if (showStats) {
System.out.format("%d (%d) - ops/sec=%,d\n", runNumber, count, ops);
}
return ops;
}
public static
class Producer implements Runnable {
private final Collection<Subscription> set;
volatile long start;
volatile long end;
private int repetitions;
volatile int count;
public
Producer(Collection<Subscription> set, int repetitions) {
this.set = set;
this.repetitions = repetitions;
}
@SuppressWarnings("unused")
@Override
public
void run() {
Collection<Subscription> set = this.set;
int i = this.repetitions;
this.start = System.nanoTime();
Iterator<Subscription> iterator;
Subscription sub;
// Entry<Subscription> current;
// Subscription sub;
int count = 0;
do {
for (iterator = set.iterator(); iterator.hasNext(); ) {
sub = iterator.next();
// if (sub.acceptsSubtypes()) {
// count--;
// } else {
count++;
// }
}
// current = set.head;
// while (current != null) {
// sub = current.getValue();
// current = current.next();
//
//// count++;
// }
} while (0 != --i);
this.end = System.nanoTime();
this.count = count;
}
}
@SuppressWarnings("unused")
public static
class Listener {
@Handler
public
void handleSync(Integer o1) {
}
@Handler(acceptVarargs = true)
public
void handleSync(Object... o) {
}
}
}