Skip to content
Snippets Groups Projects
Commit 3ac64561 authored by Christian Wulf's avatar Christian Wulf
Browse files

added more performance tests

parent 989c6656
No related branches found
No related tags found
No related merge requests found
Showing
with 542 additions and 5 deletions
...@@ -8,13 +8,16 @@ ...@@ -8,13 +8,16 @@
[irrelevant w.r.t. overhead] [irrelevant w.r.t. overhead]
-foreach vs. index-based iteration -foreach vs. index-based iteration
-iterative vs. recursive execution -iterative vs. recursive execution
-null-check vs. NullObject
- -
[analysis performance results (50%)] [analysis performance results (50%)]
2: 7400 ns 2: 7400 ns
9: 9400 ns 8: 1200 ns (iterative; argument/return w/o pipe)
9: 9400 ns (queued pipe)
10: 4900 ns (single element pipe) 10: 4900 ns (single element pipe)
11: 7400 ns (fixed sized pipe) 11: 7400 ns (fixed sized pipe)
12: 3300 ns (recursive; argument/return w/o pipe)
\ No newline at end of file 13: 3300 ns (recursive; argument/return w/o pipe; w/o pipeline class)
/***************************************************************************
* 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.MethodCallThroughputAnalysis12;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import kieker.common.logging.LogFactory;
/**
* @author Christian Wulf
*
* @since 1.10
*/
public class MethodCallThoughputTimestampAnalysis12Test {
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");
}
@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 MethodCallThroughputAnalysis12 analysis = new MethodCallThroughputAnalysis12();
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);
}
}
/***************************************************************************
* 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.MethodCallThroughputAnalysis13;
import teetime.util.StatisticsUtil;
import teetime.util.StopWatch;
import kieker.common.logging.LogFactory;
/**
* @author Christian Wulf
*
* @since 1.10
*/
public class MethodCallThoughputTimestampAnalysis13Test {
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");
}
@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 MethodCallThroughputAnalysis13 analysis = new MethodCallThroughputAnalysis13();
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);
}
}
...@@ -22,6 +22,21 @@ abstract class AbstractStage<I, O> implements StageWithPort<I, O> { ...@@ -22,6 +22,21 @@ abstract class AbstractStage<I, O> implements StageWithPort<I, O> {
private boolean reschedulable; private boolean reschedulable;
@Override
public Object executeRecursively(final Object element) {
O result = this.execute(element);
if (result == null) {
return null;
}
StageWithPort next = this.next();
// if (next != null) {
// return next.executeRecursively(result);
// } else {
// return result;
// }
return next.executeRecursively(result);
}
@Override @Override
public InputPort<I> getInputPort() { public InputPort<I> getInputPort() {
return this.inputPort; return this.inputPort;
...@@ -57,6 +72,16 @@ abstract class AbstractStage<I, O> implements StageWithPort<I, O> { ...@@ -57,6 +72,16 @@ abstract class AbstractStage<I, O> implements StageWithPort<I, O> {
return this.outputElements; return this.outputElements;
} }
// @Override
// public void executeWithPorts() {
// CommittableQueue execute;
// do {
// // execute = this.next().execute2(this.outputElements);
// // execute = this.next().execute2(this.getOutputPort().pipe.getElements());
// this.next().executeWithPorts();
// } while (this.next().isReschedulable());
// }
protected abstract void execute4(CommittableQueue<I> elements); protected abstract void execute4(CommittableQueue<I> elements);
protected abstract void execute5(I element); protected abstract void execute5(I element);
......
...@@ -22,6 +22,12 @@ public abstract class ConsumerStage<I, O> extends AbstractStage<I, O> { ...@@ -22,6 +22,12 @@ public abstract class ConsumerStage<I, O> extends AbstractStage<I, O> {
public void executeWithPorts() { public void executeWithPorts() {
I element = this.getInputPort().receive(); I element = this.getInputPort().receive();
this.execute5(element); this.execute5(element);
// this.setReschedulable(!this.getOutputPort().pipe.isEmpty());
// if (!this.getOutputPort().pipe.isEmpty()) {
// super.executeWithPorts();
// }
} }
} }
/***************************************************************************
* 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.List;
import java.util.concurrent.Callable;
import teetime.examples.throughput.TimestampObject;
import teetime.examples.throughput.methodcall.stage.CollectorSink;
import teetime.examples.throughput.methodcall.stage.NoopFilter;
import teetime.examples.throughput.methodcall.stage.ObjectProducer;
import teetime.examples.throughput.methodcall.stage.Pipeline;
import teetime.examples.throughput.methodcall.stage.StartTimestampFilter;
import teetime.examples.throughput.methodcall.stage.StopTimestampFilter;
import teetime.framework.core.Analysis;
/**
* @author Christian Wulf
*
* @since 1.10
*/
public class MethodCallThroughputAnalysis12 extends Analysis {
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 Pipeline<Void, Object> pipeline = new Pipeline<Void, Object>();
pipeline.setFirstStage(objectProducer);
pipeline.addIntermediateStage(startTimestampFilter);
pipeline.addIntermediateStages(noopFilters);
pipeline.addIntermediateStage(stopTimestampFilter);
pipeline.setLastStage(collectorSink);
pipeline.onStart();
final Runnable runnable = new Runnable() {
@Override
public void run() {
Object result;
do {
result = pipeline.executeRecursively(null);
} while (result != null);
}
};
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;
}
}
/***************************************************************************
* 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.examples.throughput.methodcall.stage.CollectorSink;
import teetime.examples.throughput.methodcall.stage.EndStage;
import teetime.examples.throughput.methodcall.stage.NoopFilter;
import teetime.examples.throughput.methodcall.stage.ObjectProducer;
import teetime.examples.throughput.methodcall.stage.StartTimestampFilter;
import teetime.examples.throughput.methodcall.stage.StopTimestampFilter;
import teetime.framework.core.Analysis;
/**
* @author Christian Wulf
*
* @since 1.10
*/
public class MethodCallThroughputAnalysis13 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]);
for (int i = 0; i < stages.length - 1; i++) {
StageWithPort<?, ?> stage = stages[i];
stage.setSuccessor(stages[i + 1]);
}
stages[stages.length - 1].setSuccessor(new EndStage<Object>());
final WrappingPipeline pipeline = new WrappingPipeline() {
private int startIndex;
@Override
public boolean execute() {
return stages[0].executeRecursively(null) != null;
}
};
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;
}
}
...@@ -23,6 +23,10 @@ public abstract class ProducerStage<I, O> extends AbstractStage<I, O> { ...@@ -23,6 +23,10 @@ public abstract class ProducerStage<I, O> extends AbstractStage<I, O> {
@Override @Override
public void executeWithPorts() { public void executeWithPorts() {
this.execute5(null); this.execute5(null);
// if (!this.getOutputPort().pipe.isEmpty()) {
// super.executeWithPorts();
// }
} }
} }
...@@ -6,6 +6,8 @@ public interface Stage<I, O> { ...@@ -6,6 +6,8 @@ public interface Stage<I, O> {
public static final Object END_SIGNAL = new Object(); public static final Object END_SIGNAL = new Object();
Object executeRecursively(Object element);
O execute(Object element); O execute(Object element);
// CommittableQueue<O> execute2(); // CommittableQueue<O> execute2();
...@@ -25,4 +27,5 @@ public interface Stage<I, O> { ...@@ -25,4 +27,5 @@ public interface Stage<I, O> {
void setSuccessor(Stage<?, ?> successor); void setSuccessor(Stage<?, ?> successor);
boolean isReschedulable(); boolean isReschedulable();
} }
...@@ -32,9 +32,6 @@ public class CollectorSink<T> extends ConsumerStage<T, Object> { ...@@ -32,9 +32,6 @@ public class CollectorSink<T> extends ConsumerStage<T, Object> {
private final List<T> elements; private final List<T> elements;
/**
* @since 1.10
*/
public CollectorSink(final List<T> list) { public CollectorSink(final List<T> list) {
this.elements = list; this.elements = list;
} }
......
package teetime.examples.throughput.methodcall.stage;
import teetime.examples.throughput.methodcall.InputPort;
import teetime.examples.throughput.methodcall.OnDisableListener;
import teetime.examples.throughput.methodcall.OutputPort;
import teetime.examples.throughput.methodcall.SchedulingInformation;
import teetime.examples.throughput.methodcall.Stage;
import teetime.examples.throughput.methodcall.StageWithPort;
import teetime.util.list.CommittableQueue;
public class EndStage<T> implements StageWithPort<T, T> {
@Override
public Object executeRecursively(final Object element) {
return this.execute(element);
}
@Override
public T execute(final Object element) {
return (T) element;
}
@Override
public CommittableQueue<T> execute2(final CommittableQueue<T> elements) {
// TODO Auto-generated method stub
return null;
}
@Override
public SchedulingInformation getSchedulingInformation() {
// TODO Auto-generated method stub
return null;
}
@Override
public Stage getParentStage() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setParentStage(final Stage parentStage, final int index) {
// TODO Auto-generated method stub
}
@Override
public void setListener(final OnDisableListener listener) {
// TODO Auto-generated method stub
}
@Override
public Stage next() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setSuccessor(final Stage<?, ?> successor) {
// TODO Auto-generated method stub
}
@Override
public boolean isReschedulable() {
// TODO Auto-generated method stub
return false;
}
@Override
public InputPort<T> getInputPort() {
// TODO Auto-generated method stub
return null;
}
@Override
public OutputPort<T> getOutputPort() {
// TODO Auto-generated method stub
return null;
}
@Override
public void executeWithPorts() {
// TODO Auto-generated method stub
}
@Override
public void setSuccessor(final StageWithPort<?, ?> successor) {
// TODO Auto-generated method stub
}
}
...@@ -72,6 +72,11 @@ public class Pipeline<I, O> implements StageWithPort<I, O>, OnDisableListener { ...@@ -72,6 +72,11 @@ public class Pipeline<I, O> implements StageWithPort<I, O>, OnDisableListener {
this.setReschedulable(this.stages[0].isReschedulable()); this.setReschedulable(this.stages[0].isReschedulable());
} }
@Override
public Object executeRecursively(final Object element) {
return this.stages[0].executeRecursively(element);
}
public void onStart() { public void onStart() {
// Pipe pipe = new Pipe(); // Pipe pipe = new Pipe();
// this.outputPort.pipe = pipe; // this.outputPort.pipe = pipe;
...@@ -113,6 +118,7 @@ public class Pipeline<I, O> implements StageWithPort<I, O>, OnDisableListener { ...@@ -113,6 +118,7 @@ public class Pipeline<I, O> implements StageWithPort<I, O>, OnDisableListener {
StageWithPort<?, ?> stage = this.stages[i]; StageWithPort<?, ?> stage = this.stages[i];
stage.setSuccessor(this.stages[i + 1]); stage.setSuccessor(this.stages[i + 1]);
} }
this.stages[this.stages.length - 1].setSuccessor(new EndStage<Object>());
} }
// //
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment