From e7ddf6c94673d2b41384742446be32e5eb0490bc Mon Sep 17 00:00:00 2001
From: Christian Wulf <chw@informatik.uni-kiel.de>
Date: Sun, 15 Jun 2014 01:49:56 +0200
Subject: [PATCH] added more performance tests

---
 ...odCallThoughputTimestampAnalysis8Test.java |  77 ++++++++++
 .../MethodCallThroughputAnalysis2.java        |   4 +-
 .../MethodCallThroughputAnalysis8.java        | 143 ++++++++++++++++++
 3 files changed, 222 insertions(+), 2 deletions(-)
 create mode 100644 src/test/java/teetime/examples/throughput/MethodCallThoughputTimestampAnalysis8Test.java
 create mode 100644 src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis8.java

diff --git a/src/test/java/teetime/examples/throughput/MethodCallThoughputTimestampAnalysis8Test.java b/src/test/java/teetime/examples/throughput/MethodCallThoughputTimestampAnalysis8Test.java
new file mode 100644
index 00000000..2f147fe8
--- /dev/null
+++ b/src/test/java/teetime/examples/throughput/MethodCallThoughputTimestampAnalysis8Test.java
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * Copyright 2014 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+package teetime.examples.throughput;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import teetime.examples.throughput.methodcall.MethodCallThroughputAnalysis8;
+import teetime.util.StatisticsUtil;
+import teetime.util.StopWatch;
+
+import kieker.common.logging.LogFactory;
+
+/**
+ * @author Christian Wulf
+ * 
+ * @since 1.10
+ */
+public class MethodCallThoughputTimestampAnalysis8Test {
+
+	private static final int NUM_OBJECTS_TO_CREATE = 100000;
+	private static final int NUM_NOOP_FILTERS = 800;
+
+	@Before
+	public void before() {
+		System.setProperty(LogFactory.CUSTOM_LOGGER_JVM, "NONE");
+	}
+
+	// 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="
+				+ NUM_NOOP_FILTERS + "...");
+		final StopWatch stopWatch = new StopWatch();
+		final List<TimestampObject> timestampObjects = new ArrayList<TimestampObject>(NUM_OBJECTS_TO_CREATE);
+
+		final MethodCallThroughputAnalysis8 analysis = new MethodCallThroughputAnalysis8();
+		analysis.setNumNoopFilters(NUM_NOOP_FILTERS);
+		analysis.setTimestampObjects(timestampObjects);
+		analysis.setInput(NUM_OBJECTS_TO_CREATE, new Callable<TimestampObject>() {
+			@Override
+			public TimestampObject call() throws Exception {
+				return new TimestampObject();
+			}
+		});
+		analysis.init();
+
+		stopWatch.start();
+		try {
+			analysis.start();
+		} finally {
+			stopWatch.end();
+		}
+
+		StatisticsUtil.printStatistics(stopWatch.getDurationInNs(), timestampObjects);
+	}
+
+}
diff --git a/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis2.java b/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis2.java
index 37e7beb1..c1c4f420 100644
--- a/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis2.java
+++ b/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis2.java
@@ -78,9 +78,9 @@ public class MethodCallThroughputAnalysis2 extends Analysis {
 				CommittableQueue<Void> inputQueue = new CommittableResizableArrayQueue<Void>(null, 0);
 				CommittableQueue<Object> outputQueue = new CommittableResizableArrayQueue<Object>(null, 0);
 
-				while (pipeline.getSchedulingInformation().isActive()) {
+				do {
 					outputQueue = pipeline.execute2(inputQueue);
-				}
+				} while (pipeline.getSchedulingInformation().isActive());
 			}
 		};
 
diff --git a/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis8.java b/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis8.java
new file mode 100644
index 00000000..916727cf
--- /dev/null
+++ b/src/test/java/teetime/examples/throughput/methodcall/MethodCallThroughputAnalysis8.java
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * Copyright 2014 Kieker Project (http://kieker-monitoring.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************/
+package teetime.examples.throughput.methodcall;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import teetime.examples.throughput.TimestampObject;
+import teetime.framework.core.Analysis;
+
+/**
+ * @author Christian Wulf
+ * 
+ * @since 1.10
+ */
+public class MethodCallThroughputAnalysis8 extends Analysis {
+
+	public abstract class WrappingPipeline {
+
+		public abstract boolean execute();
+
+	}
+
+	private long numInputObjects;
+	private Callable<TimestampObject> inputObjectCreator;
+	private int numNoopFilters;
+	private List<TimestampObject> timestampObjects;
+	private Runnable runnable;
+
+	@Override
+	public void init() {
+		super.init();
+		this.runnable = this.buildPipeline();
+	}
+
+	/**
+	 * @param numNoopFilters
+	 * @since 1.10
+	 */
+	private Runnable buildPipeline() {
+		@SuppressWarnings("unchecked")
+		final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters];
+		// create stages
+		final ObjectProducer<TimestampObject> objectProducer = new ObjectProducer<TimestampObject>(this.numInputObjects, this.inputObjectCreator);
+		final StartTimestampFilter startTimestampFilter = new StartTimestampFilter();
+		for (int i = 0; i < noopFilters.length; i++) {
+			noopFilters[i] = new NoopFilter<TimestampObject>();
+		}
+		final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter();
+		final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(this.timestampObjects);
+
+		final List<AbstractStage> stageList = new ArrayList<AbstractStage>();
+		stageList.add(objectProducer);
+		stageList.add(startTimestampFilter);
+		stageList.addAll(Arrays.asList(noopFilters));
+		stageList.add(stopTimestampFilter);
+		stageList.add(collectorSink);
+
+		// using an array decreases the performance from 60ms to 200ms (by 3x)
+		final AbstractStage[] stages = stageList.toArray(new AbstractStage[0]);
+
+		final WrappingPipeline pipeline = new WrappingPipeline() {
+			@Override
+			public boolean execute() {
+				// using the foreach for arrays (i.e., w/o using an iterator variable) increases the performance from 200ms to 130ms
+				Object element = null;
+				for (int i = 0; i < stages.length; i++) {
+					Stage stage = stages[i];
+					element = stage.execute(element);
+					if (element == null) {
+						return false;
+					}
+				}
+
+				// changing the type of stages decreases performance by 2 (e.g., NoopFilter -> Stage)
+				// the VM seems to not optimize the code anymore if the concrete type is not declared
+
+				// for (final NoopFilter<TimestampObject> noopFilter : noopFilters) {
+				// element = noopFilter.execute(element);
+				// }
+				//
+				// element = stopTimestampFilter.execute(element);
+				// element = collectorSink.execute(element);
+
+				return true;
+			}
+
+		};
+
+		final Runnable runnable = new Runnable() {
+			@Override
+			public void run() {
+				boolean success;
+				do {
+					success = pipeline.execute();
+				} while (success);
+			}
+		};
+		return runnable;
+	}
+
+	@Override
+	public void start() {
+		super.start();
+		this.runnable.run();
+	}
+
+	public void setInput(final int numInputObjects, final Callable<TimestampObject> inputObjectCreator) {
+		this.numInputObjects = numInputObjects;
+		this.inputObjectCreator = inputObjectCreator;
+	}
+
+	public int getNumNoopFilters() {
+		return this.numNoopFilters;
+	}
+
+	public void setNumNoopFilters(final int numNoopFilters) {
+		this.numNoopFilters = numNoopFilters;
+	}
+
+	public List<TimestampObject> getTimestampObjects() {
+		return this.timestampObjects;
+	}
+
+	public void setTimestampObjects(final List<TimestampObject> timestampObjects) {
+		this.timestampObjects = timestampObjects;
+	}
+}
-- 
GitLab