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