From 6f1213534a67a273da7c19b6f1caeef0248c06ca Mon Sep 17 00:00:00 2001
From: Christian Wulf <chw@informatik.uni-kiel.de>
Date: Wed, 25 Jun 2014 09:31:00 +0200
Subject: [PATCH] added performance comparison for methodcall variant

---
 .../java/teetime/util/StatisticsUtil.java     | 12 ++-
 .../list/CommittableResizableArrayQueue.java  |  6 +-
 .../methodcall/framework/core/Pipeline.java   | 14 ++--
 .../methodcall/stage/CollectorSink.java       |  5 +-
 .../variant/methodcall/stage/NoopFilter.java  |  3 +-
 .../methodcall/stage/ObjectProducer.java      |  9 ++-
 .../stage/StartTimestampFilter.java           |  3 +-
 .../methodcall/stage/StopTimestampFilter.java | 10 +--
 src/test/java/teetime/util/StopWatchTest.java |  2 +-
 .../variant/methodcall/examples/AllTests.java | 80 +++++++++++++++++++
 ...odCallThoughputTimestampAnalysis2Test.java |  3 -
 .../MethodCallThroughputAnalysis2.java        |  4 +-
 src/test/java/test/PerformanceResult.java     | 21 +++++
 src/test/java/test/PerformanceTest.java       |  2 +-
 14 files changed, 133 insertions(+), 41 deletions(-)
 create mode 100644 src/test/java/teetime/variant/methodcall/examples/AllTests.java

diff --git a/src/main/java/teetime/util/StatisticsUtil.java b/src/main/java/teetime/util/StatisticsUtil.java
index 812bf767..4708e96f 100644
--- a/src/main/java/teetime/util/StatisticsUtil.java
+++ b/src/main/java/teetime/util/StatisticsUtil.java
@@ -70,7 +70,7 @@ public class StatisticsUtil {
 
 		performanceResult.avgDurInNs = avgDurInNs;
 
-		printQuintiles(quintileValues);
+		System.out.println(getQuantilesString(quintileValues));
 
 		final long confidenceWidthInNs = StatisticsUtil.calculateConfidenceWidth(sortedDurationsInNs, avgDurInNs);
 
@@ -83,10 +83,14 @@ public class StatisticsUtil {
 		return performanceResult;
 	}
 
-	public static void printQuintiles(final Map<Double, Long> quintileValues) {
-		for (final Entry<Double, Long> entry : quintileValues.entrySet()) {
-			System.out.println((entry.getKey() * 100) + " % : " + TimeUnit.NANOSECONDS.toNanos(entry.getValue()) + " ns");
+	public static String getQuantilesString(final Map<Double, Long> quantilesValues) {
+		StringBuilder builder = new StringBuilder();
+		for (final Entry<Double, Long> entry : quantilesValues.entrySet()) {
+			String quantile = (entry.getKey() * 100) + " % : " + TimeUnit.NANOSECONDS.toNanos(entry.getValue()) + " ns";
+			builder.append(quantile);
+			builder.append("\n");
 		}
+		return builder.toString();
 	}
 
 	public static long calculateConfidenceWidth(final List<Long> durations, final long avgDurInNs) {
diff --git a/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java b/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java
index 14fab9a8..6a6b2afe 100644
--- a/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java
+++ b/src/main/java/teetime/util/list/CommittableResizableArrayQueue.java
@@ -28,9 +28,9 @@ public class CommittableResizableArrayQueue<T> implements CommittableQueue<T> {
 
 	@Override
 	public void addToTailUncommitted(final T element) {
-		// if (this.lastFreeIndexUncommitted == this.capacity()) { // TODO uncomment
-		// this.grow();
-		// }
+		if (this.lastFreeIndexUncommitted == this.capacity()) {
+			this.grow();
+		}
 		this.put(this.lastFreeIndexUncommitted++, element);
 	}
 
diff --git a/src/main/java/teetime/variant/methodcall/framework/core/Pipeline.java b/src/main/java/teetime/variant/methodcall/framework/core/Pipeline.java
index 57dcbbad..71ae10fc 100644
--- a/src/main/java/teetime/variant/methodcall/framework/core/Pipeline.java
+++ b/src/main/java/teetime/variant/methodcall/framework/core/Pipeline.java
@@ -46,12 +46,16 @@ public class Pipeline<I, O> implements Stage<I, O> {
 		// below is faster than above (probably because of the instantiation of a list iterator in each (!) execution)
 		CommittableQueue queue = elements;
 
-		// for (int i = this.startIndex; i < this.stages.length; i++) {
-		// Stage<?, ?> stage = this.stages[i];
-		// queue = stage.execute2(queue);
-		// }
+		for (int i = 0; i < this.stages.length; i++) {
+			Stage<?, ?> stage = this.stages[i];
+			queue = stage.execute2(queue);
+			if (queue.isEmpty()) {
+				break;
+			}
+		}
+
+		// queue = this.firstStage.execute2(elements);
 
-		queue = this.firstStage.execute2(elements);
 		this.setReschedulable(this.firstStage.isReschedulable());
 
 		return queue;
diff --git a/src/main/java/teetime/variant/methodcall/stage/CollectorSink.java b/src/main/java/teetime/variant/methodcall/stage/CollectorSink.java
index 49ea2928..1b2a8d3f 100644
--- a/src/main/java/teetime/variant/methodcall/stage/CollectorSink.java
+++ b/src/main/java/teetime/variant/methodcall/stage/CollectorSink.java
@@ -36,6 +36,7 @@ public class CollectorSink<T> extends ConsumerStage<T, Object> {
 		this.elements = list;
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
 	public Object execute(final Object element) {
 		this.elements.add((T) element);
@@ -57,10 +58,6 @@ public class CollectorSink<T> extends ConsumerStage<T, Object> {
 		if ((this.elements.size() % THRESHOLD) == 0) {
 			System.out.println("size: " + this.elements.size());
 		}
-
-		if (this.elements.size() > 90000) {
-			// System.out.println("size > 90000: " + this.elements.size());
-		}
 	}
 
 }
diff --git a/src/main/java/teetime/variant/methodcall/stage/NoopFilter.java b/src/main/java/teetime/variant/methodcall/stage/NoopFilter.java
index cdd44237..5907267c 100644
--- a/src/main/java/teetime/variant/methodcall/stage/NoopFilter.java
+++ b/src/main/java/teetime/variant/methodcall/stage/NoopFilter.java
@@ -34,8 +34,7 @@ public class NoopFilter<T> extends ConsumerStage<T, T> {
 	@Override
 	protected void execute4(final CommittableQueue<T> elements) {
 		T element = elements.removeFromHead();
-		// this.send(element); // "send" calls the next stage and so on
-		throw new IllegalStateException();
+		this.send(element); // TODO ? "send" calls the next stage and so on
 	}
 
 }
diff --git a/src/main/java/teetime/variant/methodcall/stage/ObjectProducer.java b/src/main/java/teetime/variant/methodcall/stage/ObjectProducer.java
index 540a81da..1d580d36 100644
--- a/src/main/java/teetime/variant/methodcall/stage/ObjectProducer.java
+++ b/src/main/java/teetime/variant/methodcall/stage/ObjectProducer.java
@@ -72,15 +72,16 @@ public class ObjectProducer<T> extends ProducerStage<Void, T> {
 
 	@Override
 	protected void execute4(final CommittableQueue<Void> elements) {
-		T newObject = null;
-		newObject = this.inputObjectCreator.create();
-		this.numInputObjects--;
-
 		if (this.numInputObjects == 0) {
 			this.setReschedulable(false);
 			// this.getOutputPort().pipe.close();
+			return;
 		}
 
+		T newObject = null;
+		newObject = this.inputObjectCreator.create();
+		this.numInputObjects--;
+
 		// System.out.println(this.getClass().getSimpleName() + ": sending " + this.numInputObjects);
 		this.send(newObject);
 		// throw new IllegalStateException();
diff --git a/src/main/java/teetime/variant/methodcall/stage/StartTimestampFilter.java b/src/main/java/teetime/variant/methodcall/stage/StartTimestampFilter.java
index 754de3dc..a83d1655 100644
--- a/src/main/java/teetime/variant/methodcall/stage/StartTimestampFilter.java
+++ b/src/main/java/teetime/variant/methodcall/stage/StartTimestampFilter.java
@@ -37,7 +37,6 @@ public class StartTimestampFilter extends ConsumerStage<TimestampObject, Timesta
 	protected void execute4(final CommittableQueue<TimestampObject> elements) {
 		TimestampObject element = elements.removeFromHead();
 		element.setStartTimestamp(System.nanoTime());
-		// this.send(element);
-		throw new IllegalStateException();
+		this.send(element);
 	}
 }
diff --git a/src/main/java/teetime/variant/methodcall/stage/StopTimestampFilter.java b/src/main/java/teetime/variant/methodcall/stage/StopTimestampFilter.java
index b855088a..1e36f533 100644
--- a/src/main/java/teetime/variant/methodcall/stage/StopTimestampFilter.java
+++ b/src/main/java/teetime/variant/methodcall/stage/StopTimestampFilter.java
@@ -33,19 +33,11 @@ public class StopTimestampFilter extends ConsumerStage<TimestampObject, Timestam
 		return timestampObject;
 	}
 
-	// @Override
-	// public void execute3() {
-	// TimestampObject element = this.getInputPort().receive();
-	// element.setStopTimestamp(System.nanoTime());
-	// // this.getOutputPort().send(element);
-	// }
-
 	@Override
 	protected void execute4(final CommittableQueue<TimestampObject> elements) {
 		TimestampObject element = elements.removeFromHead();
 		element.setStopTimestamp(System.nanoTime());
-		// this.send(element);
-		throw new IllegalStateException();
+		this.send(element);
 	}
 
 }
diff --git a/src/test/java/teetime/util/StopWatchTest.java b/src/test/java/teetime/util/StopWatchTest.java
index 8923df35..d61450e9 100644
--- a/src/test/java/teetime/util/StopWatchTest.java
+++ b/src/test/java/teetime/util/StopWatchTest.java
@@ -24,7 +24,7 @@ public class StopWatchTest {
 		}
 
 		Map<Double, Long> quintiles = StatisticsUtil.calculateQuintiles(durationsInNs);
-		StatisticsUtil.printQuintiles(quintiles);
+		StatisticsUtil.getQuantilesString(quintiles);
 	}
 
 	public static BigInteger fib(final BigInteger n) {
diff --git a/src/test/java/teetime/variant/methodcall/examples/AllTests.java b/src/test/java/teetime/variant/methodcall/examples/AllTests.java
new file mode 100644
index 00000000..9d32ae9a
--- /dev/null
+++ b/src/test/java/teetime/variant/methodcall/examples/AllTests.java
@@ -0,0 +1,80 @@
+package teetime.variant.methodcall.examples;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.junit.AfterClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import teetime.variant.methodcall.examples.experiment01.MethodCallThoughputTimestampAnalysis1Test;
+import teetime.variant.methodcall.examples.experiment02.MethodCallThoughputTimestampAnalysis2Test;
+import teetime.variant.methodcall.examples.experiment03.MethodCallThoughputTimestampAnalysis3Test;
+import teetime.variant.methodcall.examples.experiment04.MethodCallThoughputTimestampAnalysis4Test;
+import teetime.variant.methodcall.examples.experiment05.MethodCallThoughputTimestampAnalysis5Test;
+import teetime.variant.methodcall.examples.experiment06.MethodCallThoughputTimestampAnalysis6Test;
+import teetime.variant.methodcall.examples.experiment07.MethodCallThoughputTimestampAnalysis7Test;
+import teetime.variant.methodcall.examples.experiment08.MethodCallThoughputTimestampAnalysis8Test;
+import teetime.variant.methodcall.examples.experiment12.MethodCallThoughputTimestampAnalysis12Test;
+import teetime.variant.methodcall.examples.experiment13.MethodCallThoughputTimestampAnalysis13Test;
+import test.PerformanceResult;
+import test.PerformanceTest;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+	MethodCallThoughputTimestampAnalysis1Test.class,
+	MethodCallThoughputTimestampAnalysis2Test.class,
+	MethodCallThoughputTimestampAnalysis3Test.class,
+	MethodCallThoughputTimestampAnalysis4Test.class,
+	MethodCallThoughputTimestampAnalysis5Test.class,
+	MethodCallThoughputTimestampAnalysis6Test.class,
+	MethodCallThoughputTimestampAnalysis7Test.class,
+	MethodCallThoughputTimestampAnalysis8Test.class,
+	MethodCallThoughputTimestampAnalysis12Test.class,
+	MethodCallThoughputTimestampAnalysis13Test.class,
+})
+public class AllTests {
+
+	@AfterClass
+	public static void doYourOneTimeTeardown() {
+		Map<String, PerformanceResult> performanceResults = PerformanceTest.measurementRepository.performanceResults;
+		for (Entry<String, PerformanceResult> entry : performanceResults.entrySet()) {
+			System.out.println("---> " + entry.getKey() + "\n" + entry.getValue());
+		}
+
+		PerformanceResult test1 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment01.MethodCallThoughputTimestampAnalysis1Test)");
+		PerformanceResult test4 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment04.MethodCallThoughputTimestampAnalysis4Test)");
+		PerformanceResult test7 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment07.MethodCallThoughputTimestampAnalysis7Test)");
+		PerformanceResult test3 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment03.MethodCallThoughputTimestampAnalysis3Test)");
+		PerformanceResult test8 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment08.MethodCallThoughputTimestampAnalysis8Test)");
+		PerformanceResult test12 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment12.MethodCallThoughputTimestampAnalysis12Test)");
+		PerformanceResult test13 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment13.MethodCallThoughputTimestampAnalysis13Test)");
+		PerformanceResult test5 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment05.MethodCallThoughputTimestampAnalysis5Test)");
+		PerformanceResult test2 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment02.MethodCallThoughputTimestampAnalysis2Test)");
+		PerformanceResult test6 = performanceResults
+				.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment06.MethodCallThoughputTimestampAnalysis6Test)");
+
+		assertEquals(1, (double) test4.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(2, (double) test7.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(3, (double) test3.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(3, (double) test8.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(7, (double) test12.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(7, (double) test13.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(9, (double) test5.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(17, (double) test2.quantiles.get(0.5) / test1.quantiles.get(0.5), 0.1);
+		assertEquals(59, (double) test6.quantiles.get(0.5) / test1.quantiles.get(0.5), 1.1);
+	}
+
+}
diff --git a/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThoughputTimestampAnalysis2Test.java b/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThoughputTimestampAnalysis2Test.java
index 59743fcd..20da6308 100644
--- a/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThoughputTimestampAnalysis2Test.java
+++ b/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThoughputTimestampAnalysis2Test.java
@@ -28,9 +28,6 @@ import test.PerformanceTest;
  */
 public class MethodCallThoughputTimestampAnalysis2Test extends PerformanceTest {
 
-	// 500 times faster than our new framework
-	// TODO check why
-
 	@Test
 	public void testWithManyObjects() {
 		System.out.println("Testing teetime (mc) with NUM_OBJECTS_TO_CREATE=" + NUM_OBJECTS_TO_CREATE + ", NUM_NOOP_FILTERS="
diff --git a/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThroughputAnalysis2.java b/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThroughputAnalysis2.java
index 85eaebca..4baa051d 100644
--- a/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThroughputAnalysis2.java
+++ b/src/test/java/teetime/variant/methodcall/examples/experiment02/MethodCallThroughputAnalysis2.java
@@ -77,10 +77,8 @@ public class MethodCallThroughputAnalysis2 extends Analysis {
 			@Override
 			public void run() {
 				CommittableQueue<Void> inputQueue = new CommittableResizableArrayQueue<Void>(null, 0);
-				CommittableQueue<Object> outputQueue = new CommittableResizableArrayQueue<Object>(null, 0);
-
 				do {
-					outputQueue = pipeline.execute2(inputQueue);
+					pipeline.execute2(inputQueue);
 				} while (pipeline.isReschedulable());
 			}
 		};
diff --git a/src/test/java/test/PerformanceResult.java b/src/test/java/test/PerformanceResult.java
index a6a5b1a7..34f94507 100644
--- a/src/test/java/test/PerformanceResult.java
+++ b/src/test/java/test/PerformanceResult.java
@@ -2,6 +2,8 @@ package test;
 
 import java.util.Map;
 
+import teetime.util.StatisticsUtil;
+
 public class PerformanceResult {
 
 	public long sumInNs;
@@ -9,4 +11,23 @@ public class PerformanceResult {
 	public long avgDurInNs;
 	public long confidenceWidthInNs;
 
+	@Override
+	public String toString() {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("sumInNs: ");
+		stringBuilder.append(this.sumInNs);
+		stringBuilder.append("\n");
+
+		stringBuilder.append("avgDurInNs: ");
+		stringBuilder.append(this.avgDurInNs);
+		stringBuilder.append("\n");
+
+		stringBuilder.append("confidenceWidthInNs: ");
+		stringBuilder.append(this.confidenceWidthInNs);
+		stringBuilder.append("\n");
+
+		stringBuilder.append(StatisticsUtil.getQuantilesString(this.quantiles));
+
+		return stringBuilder.toString();
+	}
 }
diff --git a/src/test/java/test/PerformanceTest.java b/src/test/java/test/PerformanceTest.java
index 910053b0..d3982b48 100644
--- a/src/test/java/test/PerformanceTest.java
+++ b/src/test/java/test/PerformanceTest.java
@@ -21,7 +21,7 @@ public abstract class PerformanceTest {
 	protected static final int NUM_OBJECTS_TO_CREATE = 100000;
 	protected static final int NUM_NOOP_FILTERS = 800;
 
-	private static MeasurementRepository measurementRepository = new MeasurementRepository();
+	public static final MeasurementRepository measurementRepository = new MeasurementRepository();
 
 	private Description description;
 
-- 
GitLab