/******************************************************************************* * Copyright 2014 Analog Devices, Inc. * * 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 com.analog.lyric.benchmarking; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import com.google.common.reflect.ClassPath; public class BenchmarkRunner { private static DataCollector _executionTimeCollector = new ExecutionTimeCollector(); private static DataCollector _gcDataCollector = new GCDataCollector(); private static MemoryUsageSamplingCollector _memoryUsageSamplingCollector = new MemoryUsageSamplingCollector(); public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { if (args.length != 1) { throw new IllegalArgumentException("Specify benchmark class."); } String benchmarkPackageName = args[0]; runBenchmarkPackage(benchmarkPackageName); // String testClassName = args[0]; // runBenchmarkClass(testClassName); } public static void runBenchmarkPackage(String packageName) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { applyStrategy(packageName, new BenchmarkPackageRunnerStrategy( packageName)); } public static void runBenchmarkClass(String qualifiedClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { applyStrategy(qualifiedClassName, new BenchmarkClassRunnerStrategy( qualifiedClassName)); } public static void runBenchmarkMethod(String qualifiedMethodName) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SecurityException, NoSuchMethodException { if (qualifiedMethodName.endsWith("()")) { qualifiedMethodName = qualifiedMethodName.substring(0, qualifiedMethodName.length() - 2); } int p = qualifiedMethodName.lastIndexOf('.'); String className = qualifiedMethodName.substring(0, p); String methodName = qualifiedMethodName.substring(p + 1); applyStrategy(qualifiedMethodName, new BenchmarkMethodRunnerStrategy( className, methodName)); } private interface Strategy { void apply(BenchmarkCreator benchmarkCreator) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException; } private static void applyStrategy(String label, Strategy strategy) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { System.out.println("Classpath:"); System.out.println(System.getProperty("java.class.path")); BenchmarkCreator benchmarkCreator = new BenchmarkCreator(label); BenchmarkDataset benchmarkDataset = benchmarkCreator .getBenchmarkDataset(); String configuration = benchmarkDataset.getProperties().getProperty( "hostname"); configuration = configuration + "/java"; benchmarkDataset.getProperties().setProperty("configuration", configuration); strategy.apply(benchmarkCreator); BenchmarkDatasetXmlSerializer serializer = new BenchmarkDatasetXmlSerializer(); String outputFilename = String.format( "%s_%s", configuration, benchmarkCreator.getBenchmarkDataset().getProperties() .getProperty("create.date")).replaceAll("\\W+", "_") + ".xml"; Writer writer = null; try { FileOutputStream fileOutputStream = new FileOutputStream( outputFilename); writer = new OutputStreamWriter(fileOutputStream, "UTF8"); serializer.serialize(writer, benchmarkDataset); } catch (IOException e) { e.printStackTrace(); } finally { if (writer != null) { writer.close(); } } } private static class BenchmarkPackageRunnerStrategy implements Strategy { private final String _packageName; public BenchmarkPackageRunnerStrategy(String packageName) { _packageName = packageName; } public void apply(BenchmarkCreator benchmarkCreator) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { ClassPath classpath = ClassPath.from(ClassLoader .getSystemClassLoader()); for (ClassPath.ClassInfo classInfo : classpath .getTopLevelClassesRecursive(_packageName)) { if (classInfo.getSimpleName().endsWith("Benchmark")) { BenchmarkClassRunnerStrategy classRunner = new BenchmarkClassRunnerStrategy( classInfo.getName()); classRunner.apply(benchmarkCreator); } } } } private static class BenchmarkClassRunnerStrategy implements Strategy { private final String _className; public BenchmarkClassRunnerStrategy(String className) { _className = className; } public void apply(BenchmarkCreator benchmarkCreator) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class<?> testClass = Class.forName(_className); final Object testClassInstance = testClass.newInstance(); Method[] methods = testClass.getMethods(); ArrayList<Method> annotated = new ArrayList<Method>(); for (Method m : methods) { if (m.isAnnotationPresent(Benchmark.class)) { annotated.add(m); } } for (Method m : annotated) { BenchmarkMethodRunnerStrategy methodRunner = new BenchmarkMethodRunnerStrategy( testClassInstance, m); methodRunner.apply(benchmarkCreator); } } } private static class BenchmarkMethodRunnerStrategy implements Strategy { private final Object _testClassInstance; private final Method _method; public BenchmarkMethodRunnerStrategy(Object testClassInstance, Method method) { _testClassInstance = testClassInstance; _method = method; } public BenchmarkMethodRunnerStrategy(String className, String methodName) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException { Class<?> testClass = Class.forName(className); _testClassInstance = testClass.newInstance(); _method = testClass.getMethod(methodName); } public void apply(BenchmarkCreator benchmarkCreator) { System.out.printf("Benchmark '%s'...\n", _method.getName()); Benchmark annotation = _method.getAnnotation(Benchmark.class); final Method mf = _method; IterationRunner runnable = new IterationRunner() { @Override public boolean run() { boolean abort = true; try { mf.invoke(_testClassInstance); abort = false; } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return abort; } }; benchmarkCreator.doRun(_method.getName(), annotation.warmupIterations(), annotation.iterations(), annotation.doGC(), runnable, _executionTimeCollector, _gcDataCollector, _memoryUsageSamplingCollector); } } }