/******************************************************************************* * Copyright (c) 2009, 2010 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation ******************************************************************************/ package org.eclipse.ocl.examples.impactanalyzer.benchmark.execution; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.ocl.examples.impactanalyzer.benchmark.PathOptions; import org.eclipse.ocl.examples.impactanalyzer.benchmark.ProcessingOptions; import org.eclipse.ocl.examples.impactanalyzer.benchmark.execution.measurements.BenchmarkMeasurements; import org.eclipse.ocl.examples.impactanalyzer.benchmark.postprocessing.BenchmarkResultWriter; import org.eclipse.ocl.examples.impactanalyzer.benchmark.preparation.tasks.BenchmarkTask; /** * The {@link StandardBenchmarkExecutor} benchmarks {@link BenchmarkTasks} by measuring * per System.nanoTime() before and after executing the task. * * It executes a {@link BenchmarkTask} several times in order to see effects of * caching and initalization. However, it does not respect other well-known * rules for micro-benchmarking Java code. * * @author Manuel Holzleitner (D049667) */ public class StandardBenchmarkExecutor implements BenchmarkExecutor { private final HashMap<String, Throwable> notExecutedDueToException; private int exceptionCount = 0; public StandardBenchmarkExecutor() { if (PathOptions.isExceptionDumpFilePathDefined()) { notExecutedDueToException = new LinkedHashMap<String, Throwable>(); } else { notExecutedDueToException = null; } } public void execute(BenchmarkTask task, BenchmarkResultWriter writer) { try { if (task.activate()) { // Warmup for (int i = 0; i < ProcessingOptions.getNumberOfWarmUps(); i++) { task.beforeCall(); task.call(); task.callEvaluation(); task.afterCall(); task.getAdditionalMeasurementInformation(); } ArrayList<Long> executionTimeList = new ArrayList<Long>(); ArrayList<Long> evaluationTimeList = new ArrayList<Long>(); ArrayList<Map<String, String>> additionalMeasurementInformationList = new ArrayList<Map<String, String>>(); for (int i = 0; i < ProcessingOptions.getNumberOfMeasures(); i++) { measureExecutionTime(task, executionTimeList, evaluationTimeList, additionalMeasurementInformationList); BenchmarkMeasurements.aggregate(); } task.deactivate(); writer.writeDataSet(task.getAdditionalInformation(), executionTimeList, evaluationTimeList, additionalMeasurementInformationList, BenchmarkMeasurements.getMeasurementList()); BenchmarkMeasurements.reset(); } } catch (Exception e) { if (notExecutedDueToException != null) { notExecutedDueToException.put(task.toString(), e); } exceptionCount++; if (ProcessingOptions.isVerbose()) { e.printStackTrace(); } } catch (StackOverflowError e) { if (notExecutedDueToException != null) { notExecutedDueToException.put(task.toString(), e); } exceptionCount++; if (ProcessingOptions.isVerbose()) { e.printStackTrace(); } } } public int getExceptionCount() { return exceptionCount; } private void measureExecutionTime(BenchmarkTask task, ArrayList<Long> executionTimeList, ArrayList<Long> evaluationTimeList, ArrayList<Map<String, String>> additionalMeasurementInformationList) throws Exception { // Perform measurement task.beforeCall(); long timeBefore = System.nanoTime(); task.call(); long timeAfter = System.nanoTime(); long timeBeforeEvaluation = System.nanoTime(); task.callEvaluation(); long timeAfterEvaluation = System.nanoTime(); task.afterCall(); executionTimeList.add(new Long(timeAfter - timeBefore)); evaluationTimeList.add(new Long(timeAfterEvaluation - timeBeforeEvaluation)); additionalMeasurementInformationList.add(task.getAdditionalMeasurementInformation()); } /** * exceptions will only be recorded if {@link PathOptions#isExceptionDumpFilePathDefined()} returns * <code>true</code>. * * @return a read-only map */ public Map<String, Throwable> getNotExecutedDueToException() { return notExecutedDueToException == null ? null : Collections.unmodifiableMap(notExecutedDueToException); } public void clearExceptions() { if (notExecutedDueToException != null) { notExecutedDueToException.clear(); } } }