/*******************************************************************************
* 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);
}
}
}