diff options
author | Elliott Hughes <enh@google.com> | 2010-02-19 22:17:32 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2010-02-19 22:17:32 -0800 |
commit | 4e4e85e4fd35927205c08ca6626f33fd0490270a (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src | |
parent | f062bf49c71013ec19cb71218778299535aceaa8 (diff) | |
download | caliper-4e4e85e4fd35927205c08ca6626f33fd0490270a.tar.gz |
Remove external/caliper.
Diffstat (limited to 'src')
39 files changed, 0 insertions, 3943 deletions
diff --git a/src/CaliperCore.gwt.xml b/src/CaliperCore.gwt.xml deleted file mode 100644 index 161ac57..0000000 --- a/src/CaliperCore.gwt.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module> - <inherits name='com.google.gwt.user.User'/> - <source path="com/google/caliper"> - <include name="**/Run.java"/> - <include name="**/Scenario.java"/> - </source> -</module>
\ No newline at end of file diff --git a/src/com/google/caliper/Arguments.java b/src/com/google/caliper/Arguments.java deleted file mode 100644 index e5ff0f7..0000000 --- a/src/com/google/caliper/Arguments.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2010 Google 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.google.caliper; - -import com.google.caliper.UserException.DisplayUsageException; -import com.google.caliper.UserException.MalformedParameterException; -import com.google.caliper.UserException.MultipleBenchmarkClassesException; -import com.google.caliper.UserException.NoBenchmarkClassException; -import com.google.caliper.UserException.UnrecognizedOptionException; -import com.google.common.collect.Iterators; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * Parse command line arguments for the runner and in-process runner. - */ -public final class Arguments { - private String suiteClassName; - - /** JVMs to run in the benchmark */ - private final Set<String> userVms = new LinkedHashSet<String>(); - - /** - * Parameter values specified by the user on the command line. Parameters with - * no value in this multimap will get their values from the benchmark suite. - */ - private final Multimap<String, String> userParameters = LinkedHashMultimap.create(); - - private long warmupMillis = 5000; - private long runMillis = 5000; - - /** The URL to post benchmark results to. */ - private String postHost = "http://microbenchmarks.appspot.com/run/"; - - public String getSuiteClassName() { - return suiteClassName; - } - - public Set<String> getUserVms() { - return userVms; - } - - public Multimap<String, String> getUserParameters() { - return userParameters; - } - - public long getWarmupMillis() { - return warmupMillis; - } - - public long getRunMillis() { - return runMillis; - } - - public String getPostHost() { - return postHost; - } - - public static Arguments parse(String[] argsArray) { - Arguments result = new Arguments(); - - Iterator<String> args = Iterators.forArray(argsArray); - while (args.hasNext()) { - String arg = args.next(); - - if ("--help".equals(arg)) { - throw new DisplayUsageException(); - } - - if ("--postHost".equals(arg)) { - result.postHost = args.next(); - - } else if (arg.startsWith("-D")) { - int equalsSign = arg.indexOf('='); - if (equalsSign == -1) { - throw new MalformedParameterException(arg); - } - String name = arg.substring(2, equalsSign); - String value = arg.substring(equalsSign + 1); - result.userParameters.put(name, value); - - } else if ("--warmupMillis".equals(arg)) { - result.warmupMillis = Long.parseLong(args.next()); - - } else if ("--runMillis".equals(arg)) { - result.runMillis = Long.parseLong(args.next()); - - } else if ("--vm".equals(arg)) { - result.userVms.add(args.next()); - - } else if (arg.startsWith("-")) { - throw new UnrecognizedOptionException(arg); - - } else { - if (result.suiteClassName != null) { - throw new MultipleBenchmarkClassesException(result.suiteClassName, arg); - } - result.suiteClassName = arg; - } - } - - if (result.suiteClassName == null) { - throw new NoBenchmarkClassException(); - } - - return result; - } - - public static void printUsage() { - Arguments defaults = new Arguments(); - - System.out.println(); - System.out.println("Usage: Runner [OPTIONS...] <benchmark>"); - System.out.println(); - System.out.println(" <benchmark>: a benchmark class or suite"); - System.out.println(); - System.out.println("OPTIONS"); - System.out.println(); - System.out.println(" -D<param>=<value>: fix a benchmark parameter to a given value."); - System.out.println(" When multiple values for the same parameter are given (via"); - System.out.println(" multiple --Dx=y args), all supplied values are used."); - System.out.println(); - System.out.println(" --inProcess: run the benchmark in the same JVM rather than spawning"); - System.out.println(" another with the same classpath. By default each benchmark is"); - System.out.println(" run in a separate VM"); - System.out.println(); - System.out.println(" --postHost <host>: the URL to post benchmark results to, or \"none\""); - System.out.println(" to skip posting results to the web."); - System.out.println(" default value: " + defaults.postHost); - System.out.println(); - System.out.println(" --warmupMillis <millis>: duration to warmup each benchmark"); - System.out.println(); - System.out.println(" --runMillis <millis>: duration to execute each benchmark"); - System.out.println(); - System.out.println(" --vm <vm>: executable to test benchmark on"); - - // adding new options? don't forget to update executeForked() - } -} diff --git a/src/com/google/caliper/Benchmark.java b/src/com/google/caliper/Benchmark.java deleted file mode 100644 index b5d35f9..0000000 --- a/src/com/google/caliper/Benchmark.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import java.util.Map; -import java.util.Set; - -/** - * A collection of benchmarks that share a set of configuration parameters. - */ -public interface Benchmark { - - Set<String> parameterNames(); - - Set<String> parameterValues(String parameterName); - - TimedRunnable createBenchmark(Map<String, String> parameterValues); -}
\ No newline at end of file diff --git a/src/com/google/caliper/Caliper.java b/src/com/google/caliper/Caliper.java deleted file mode 100644 index 6c9d625..0000000 --- a/src/com/google/caliper/Caliper.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (C) 2009 Google 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.google.caliper; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Measure's the benchmark's per-trial execution time. - */ -class Caliper { - - private final long warmupNanos; - private final long runNanos; - - Caliper(long warmupMillis, long runMillis) { - checkArgument(warmupMillis > 50); - checkArgument(runMillis > 50); - - this.warmupNanos = warmupMillis * 1000000; - this.runNanos = runMillis * 1000000; - } - - public double warmUp(TimedRunnable timedRunnable) throws Exception { - long startNanos = System.nanoTime(); - long endNanos = startNanos + warmupNanos; - long currentNanos; - int netReps = 0; - int reps = 1; - - /* - * Run progressively more reps at a time until we cross our warmup - * threshold. This way any just-in-time compiler will be comfortable running - * multiple iterations of our measurement method. - */ - while ((currentNanos = System.nanoTime()) < endNanos) { - timedRunnable.run(reps); - netReps += reps; - reps *= 2; - } - - double nanosPerExecution = (currentNanos - startNanos) / (double) netReps; - if (nanosPerExecution > 1000000000 || nanosPerExecution < 2) { - throw new ConfigurationException("Runtime " + nanosPerExecution + " out of range"); - } - return nanosPerExecution; - } - - /** - * In the run proper, we predict how extrapolate based on warmup how many - * runs we're going to need, and run them all in a single batch. - */ - public double run(TimedRunnable test, double estimatedNanosPerTrial) - throws Exception { - @SuppressWarnings("NumericCastThatLosesPrecision") - int trials = (int) (runNanos / estimatedNanosPerTrial); - if (trials == 0) { - trials = 1; - } - - double nanosPerTrial = measure(test, trials); - - // if the runtime was in the expected range, return it. We're good. - if (isPlausible(estimatedNanosPerTrial, nanosPerTrial)) { - return nanosPerTrial; - } - - // The runtime was outside of the expected range. Perhaps the VM is inlining - // things too aggressively? We'll run more rounds to confirm that the - // runtime scales with the number of trials. - double nanosPerTrial2 = measure(test, trials * 4); - if (isPlausible(nanosPerTrial, nanosPerTrial2)) { - return nanosPerTrial; - } - - throw new ConfigurationException("Measurement error: " - + "runtime isn't proportional to the number of repetitions!"); - } - - /** - * Returns true if the given measurement is consistent with the expected - * measurement. - */ - private boolean isPlausible(double expected, double measurement) { - double ratio = measurement / expected; - return ratio > 0.5 && ratio < 2.0; - } - - private double measure(TimedRunnable test, int trials) throws Exception { - prepareForTest(); - long startNanos = System.nanoTime(); - test.run(trials); - return (System.nanoTime() - startNanos) / (double) trials; - } - - private void prepareForTest() { - System.gc(); - System.gc(); - } -}
\ No newline at end of file diff --git a/src/com/google/caliper/ConfigurationException.java b/src/com/google/caliper/ConfigurationException.java deleted file mode 100644 index c4a35ec..0000000 --- a/src/com/google/caliper/ConfigurationException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -/** - * Thrown upon occurrence of a configuration error. - */ -final class ConfigurationException extends RuntimeException { - - ConfigurationException(String s) { - super(s); - } - - ConfigurationException(Throwable cause) { - super(cause); - } - - private static final long serialVersionUID = 0; -} diff --git a/src/com/google/caliper/ConsoleReport.java b/src/com/google/caliper/ConsoleReport.java deleted file mode 100644 index e59ceb6..0000000 --- a/src/com/google/caliper/ConsoleReport.java +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Copyright (C) 2009 Google 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.google.caliper; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Ordering; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * Prints a report containing the tested values and the corresponding - * measurements. Measurements are grouped by variable using indentation. - * Alongside numeric values, quick-glance ascii art bar charts are printed. - * Sample output: - * <pre> - * benchmark d ns logarithmic runtime - * ConcatenationBenchmark 3.141592653589793 4397 |||||||||||||||||||||||| - * ConcatenationBenchmark -0.0 223 ||||||||||||||| - * FormatterBenchmark 3.141592653589793 33999 |||||||||||||||||||||||||||||| - * FormatterBenchmark -0.0 26399 ||||||||||||||||||||||||||||| - * </pre> - */ -final class ConsoleReport { - - private static final int bargraphWidth = 30; - - private final List<Variable> variables; - private final Run run; - private final List<Scenario> scenarios; - - private final double maxValue; - private final double logMaxValue; - private final int decimalDigits; - private final double divideBy; - private final String units; - private final int measurementColumnLength; - - ConsoleReport(Run run) { - this.run = run; - - double min = Double.POSITIVE_INFINITY; - double max = 0; - - Multimap<String, String> nameToValues = LinkedHashMultimap.create(); - List<Variable> variablesBuilder = new ArrayList<Variable>(); - for (Map.Entry<Scenario, Double> entry : run.getMeasurements().entrySet()) { - Scenario scenario = entry.getKey(); - double d = entry.getValue(); - - min = Math.min(min, d); - max = Math.max(max, d); - - for (Map.Entry<String, String> variable : scenario.getVariables().entrySet()) { - String name = variable.getKey(); - nameToValues.put(name, variable.getValue()); - } - } - - for (Map.Entry<String, Collection<String>> entry : nameToValues.asMap().entrySet()) { - Variable variable = new Variable(entry.getKey(), entry.getValue()); - variablesBuilder.add(variable); - } - - /* - * Figure out how much influence each variable has on the measured value. - * We sum the measurements taken with each value of each variable. For - * variable that have influence on the measurement, the sums will differ - * by value. If the variable has little influence, the sums will be similar - * to one another and close to the overall average. We take the standard - * deviation across each variable's collection of sums. Higher standard - * deviation implies higher influence on the measured result. - */ - double sumOfAllMeasurements = 0; - for (double measurement : run.getMeasurements().values()) { - sumOfAllMeasurements += measurement; - } - for (Variable variable : variablesBuilder) { - int numValues = variable.values.size(); - double[] sumForValue = new double[numValues]; - for (Map.Entry<Scenario, Double> entry : run.getMeasurements().entrySet()) { - Scenario scenario = entry.getKey(); - sumForValue[variable.index(scenario)] += entry.getValue(); - } - double mean = sumOfAllMeasurements / sumForValue.length; - double stdDeviationSquared = 0; - for (double value : sumForValue) { - double distance = value - mean; - stdDeviationSquared += distance * distance; - } - variable.stdDeviation = Math.sqrt(stdDeviationSquared / numValues); - } - - this.variables = new StandardDeviationOrdering().reverse().sortedCopy(variablesBuilder); - this.scenarios = new ByVariablesOrdering().sortedCopy(run.getMeasurements().keySet()); - this.maxValue = max; - this.logMaxValue = Math.log(max); - - int numDigitsInMin = ceil(Math.log10(min)); - if (numDigitsInMin > 9) { - divideBy = 1000000000; - decimalDigits = Math.max(0, 9 + 3 - numDigitsInMin); - units = "s"; - } else if (numDigitsInMin > 6) { - divideBy = 1000000; - decimalDigits = Math.max(0, 6 + 3 - numDigitsInMin); - units = "ms"; - } else if (numDigitsInMin > 3) { - divideBy = 1000; - decimalDigits = Math.max(0, 3 + 3 - numDigitsInMin); - units = "us"; - } else { - divideBy = 1; - decimalDigits = 0; - units = "ns"; - } - measurementColumnLength = max > 0 - ? ceil(Math.log10(max / divideBy)) + decimalDigits + 1 - : 1; - } - - /** - * A variable and the set of values to which it has been assigned. - */ - private static class Variable { - final String name; - final ImmutableList<String> values; - final int maxLength; - double stdDeviation; - - Variable(String name, Collection<String> values) { - this.name = name; - this.values = ImmutableList.copyOf(values); - - int maxLen = name.length(); - for (String value : values) { - maxLen = Math.max(maxLen, value.length()); - } - this.maxLength = maxLen; - } - - String get(Scenario scenario) { - return scenario.getVariables().get(name); - } - - int index(Scenario scenario) { - return values.indexOf(get(scenario)); - } - - boolean isInteresting() { - return values.size() > 1; - } - } - - /** - * Orders the different variables by their standard deviation. This results - * in an appropriate grouping of output values. - */ - private static class StandardDeviationOrdering extends Ordering<Variable> { - public int compare(Variable a, Variable b) { - return Double.compare(a.stdDeviation, b.stdDeviation); - } - } - - /** - * Orders scenarios by the variables. - */ - private class ByVariablesOrdering extends Ordering<Scenario> { - public int compare(Scenario a, Scenario b) { - for (Variable variable : variables) { - int aValue = variable.values.indexOf(variable.get(a)); - int bValue = variable.values.indexOf(variable.get(b)); - int diff = aValue - bValue; - if (diff != 0) { - return diff; - } - } - return 0; - } - } - - void displayResults() { - printValues(); - System.out.println(); - printUninterestingVariables(); - } - - /** - * Prints a table of values. - */ - private void printValues() { - // header - for (Variable variable : variables) { - if (variable.isInteresting()) { - System.out.printf("%" + variable.maxLength + "s ", variable.name); - } - } - System.out.printf("%" + measurementColumnLength + "s logarithmic runtime%n", units); - - // rows - String numbersFormat = "%" + measurementColumnLength + "." + decimalDigits + "f %s%n"; - for (Scenario scenario : scenarios) { - for (Variable variable : variables) { - if (variable.isInteresting()) { - System.out.printf("%" + variable.maxLength + "s ", variable.get(scenario)); - } - } - double measurement = run.getMeasurements().get(scenario); - System.out.printf(numbersFormat, measurement / divideBy, bargraph(measurement)); - } - } - - /** - * Prints variables with only one unique value. - */ - private void printUninterestingVariables() { - for (Variable variable : variables) { - if (!variable.isInteresting()) { - System.out.println(variable.name + ": " + Iterables.getOnlyElement(variable.values)); - } - } - } - - /** - * Returns a string containing a bar of proportional width to the specified - * value. - */ - private String bargraph(double value) { - int numLinearChars = floor(value / maxValue * bargraphWidth); - double logValue = Math.log(value); - int numChars = floor(logValue / logMaxValue * bargraphWidth); - StringBuilder sb = new StringBuilder(numChars); - for (int i = 0; i < numLinearChars; i++) { - sb.append("X"); - } - - for (int i = numLinearChars; i < numChars; i++) { - sb.append("|"); - } - return sb.toString(); - } - - @SuppressWarnings("NumericCastThatLosesPrecision") - private static int floor(double d) { - return (int) d; - } - - @SuppressWarnings("NumericCastThatLosesPrecision") - private static int ceil(double d) { - return (int) Math.ceil(d); - } -} diff --git a/src/com/google/caliper/InProcessRunner.java b/src/com/google/caliper/InProcessRunner.java deleted file mode 100644 index 33e9e00..0000000 --- a/src/com/google/caliper/InProcessRunner.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2010 Google 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.google.caliper; - -import com.google.caliper.UserException.CantCustomizeInProcessVmException; -import com.google.caliper.UserException.ExceptionFromUserCodeException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; - -/** - * Executes a benchmark in the current VM. - */ -final class InProcessRunner { - - public void run(String... args) { - Arguments arguments = Arguments.parse(args); - - if (!arguments.getUserVms().isEmpty()) { - throw new CantCustomizeInProcessVmException(); - } - - ScenarioSelection scenarioSelection = new ScenarioSelection(arguments); - - PrintStream resultStream = System.out; - System.setOut(nullPrintStream()); - System.setErr(nullPrintStream()); - - try { - Caliper caliper = new Caliper(arguments.getWarmupMillis(), arguments.getRunMillis()); - - for (Scenario scenario : scenarioSelection.select()) { - TimedRunnable timedRunnable = scenarioSelection.createBenchmark(scenario); - double warmupNanosPerTrial = caliper.warmUp(timedRunnable); - double nanosPerTrial = caliper.run(timedRunnable, warmupNanosPerTrial); - resultStream.println(nanosPerTrial); - } - } catch (Exception e) { - throw new ExceptionFromUserCodeException(e); - } - } - - public static void main(String... args) { - try { - new InProcessRunner().run(args); - } catch (UserException e) { - e.display(); // TODO: send this to the host process - System.exit(1); - } - } - - public PrintStream nullPrintStream() { - return new PrintStream(new OutputStream() { - public void write(int b) throws IOException {} - }); - } -} diff --git a/src/com/google/caliper/Param.java b/src/com/google/caliper/Param.java deleted file mode 100644 index bea0269..0000000 --- a/src/com/google/caliper/Param.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotates the field accepting a parameter in a {@link SimpleBenchmark}. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Param { - /** - * One or more default values, as strings, that this parameter should be given if none are - * specified on the command line. If values are specified on the command line, the defaults given - * here are all ignored. - */ - String[] value() default {}; -} diff --git a/src/com/google/caliper/Parameter.java b/src/com/google/caliper/Parameter.java deleted file mode 100644 index caca252..0000000 --- a/src/com/google/caliper/Parameter.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -/** - * A parameter in a {@link SimpleBenchmark}. - */ -abstract class Parameter<T> { - - private final Field field; - - private Parameter(Field field) { - this.field = field; - } - - /** - * Returns all properties for the given class. - */ - public static Map<String, Parameter<?>> forClass(Class<? extends Benchmark> suiteClass) { - Map<String, Parameter<?>> parameters = new TreeMap<String, Parameter<?>>(); - for (Field field : suiteClass.getDeclaredFields()) { - if (field.isAnnotationPresent(Param.class)) { - field.setAccessible(true); - Parameter<?> parameter = forField(suiteClass, field); - parameters.put(parameter.getName(), parameter); - } - } - return parameters; - } - - private static Parameter<?> forField( - Class<? extends Benchmark> suiteClass, final Field field) { - // First check for String values on the annotation itself - final Object[] defaults = field.getAnnotation(Param.class).value(); - if (defaults.length > 0) { - return new Parameter<Object>(field) { - @Override public Collection<Object> values() throws Exception { - return Arrays.asList(defaults); - } - }; - // TODO: or should we continue so we can give an error/warning if params are also give in a - // method or field? - } - - Parameter<?> result = null; - Type returnType = null; - Member member = null; - - // Now check for a fooValues() method - try { - final Method valuesMethod = suiteClass.getDeclaredMethod(field.getName() + "Values"); - valuesMethod.setAccessible(true); - member = valuesMethod; - returnType = valuesMethod.getGenericReturnType(); - result = new Parameter<Object>(field) { - @SuppressWarnings("unchecked") // guarded below - @Override public Collection<Object> values() throws Exception { - return (Collection<Object>) valuesMethod.invoke(null); - } - }; - } catch (NoSuchMethodException ignored) { - } - - // Now check for a fooValues field - try { - final Field valuesField = suiteClass.getDeclaredField(field.getName() + "Values"); - valuesField.setAccessible(true); - member = valuesField; - if (result != null) { - throw new ConfigurationException("Two values members defined for " + field); - } - returnType = valuesField.getGenericType(); - result = new Parameter<Object>(field) { - @SuppressWarnings("unchecked") // guarded below - @Override public Collection<Object> values() throws Exception { - return (Collection<Object>) valuesField.get(null); - } - }; - } catch (NoSuchFieldException ignored) { - } - - if (member != null && !Modifier.isStatic(member.getModifiers())) { - throw new ConfigurationException("Values member must be static " + member); - } - - // If there isn't a values member but the parameter is an enum, we default - // to EnumSet.allOf. - if (member == null && field.getType().isEnum()) { - returnType = Collection.class; - result = new Parameter<Object>(field) { - // TODO: figure out the simplest way to make this compile and be green in IDEA too - @SuppressWarnings({"unchecked", "RawUseOfParameterizedType", "RedundantCast"}) - // guarded above - @Override public Collection<Object> values() throws Exception { - Set<Enum> set = EnumSet.allOf((Class<Enum>) field.getType()); - return (Collection) set; - } - }; - } - - if (result == null) { - return new Parameter<Object>(field) { - @Override public Collection<Object> values() { - // TODO: need tests to make sure this fails properly when no cmdline params given and - // works properly when they are given - return Collections.emptySet(); - } - }; - } else if (!isValidReturnType(returnType)) { - throw new ConfigurationException("Invalid return type " + returnType - + " for values member " + member + "; must be Collection"); - } - return result; - } - - private static boolean isValidReturnType(Type returnType) { - if (returnType == Collection.class) { - return true; - } - if (returnType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) returnType; - if (type.getRawType() == Collection.class) { - return true; - } - } - return false; - } - - /** - * Sets the value of this property to the specified value for the given suite. - */ - public void set(Benchmark suite, Object value) throws Exception { - field.set(suite, value); - } - - /** - * Returns the available values of the property as specified by the suite. - */ - public abstract Collection<T> values() throws Exception; - - /** - * Returns the parameter's type, such as double.class. - */ - public Type getType() { - return field.getGenericType(); - } - - /** - * Returns the field's name. - */ - String getName() { - return field.getName(); - } -} diff --git a/src/com/google/caliper/Run.java b/src/com/google/caliper/Run.java deleted file mode 100644 index f2e71de..0000000 --- a/src/com/google/caliper/Run.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright (C) 2009 Google 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.google.caliper; - -import java.io.Serializable; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * The complete result of a benchmark suite run. - * - * <p>Gwt-safe. - */ -public final class Run - implements Serializable /* for GWT Serialization */ { - - private /*final*/ Map<Scenario, Double> measurements; - private /*final*/ String benchmarkName; - private /*final*/ String executedByUuid; - private /*final*/ long executedTimestamp; - - // TODO: add more run properites such as checksums of the executed code - - public Run(Map<Scenario, Double> measurements, - String benchmarkName, String executedByUuid, Date executedTimestamp) { - if (benchmarkName == null || executedByUuid == null || executedTimestamp == null) { - throw new NullPointerException(); - } - - this.measurements = new LinkedHashMap<Scenario, Double>(measurements); - this.benchmarkName = benchmarkName; - this.executedByUuid = executedByUuid; - this.executedTimestamp = executedTimestamp.getTime(); - } - - public Map<Scenario, Double> getMeasurements() { - return measurements; - } - - public String getBenchmarkName() { - return benchmarkName; - } - - public String getExecutedByUuid() { - return executedByUuid; - } - - public Date getExecutedTimestamp() { - return new Date(executedTimestamp); - } - - @Override public boolean equals(Object o) { - if (o instanceof Run) { - Run that = (Run) o; - return measurements.equals(that.measurements) - && benchmarkName.equals(that.benchmarkName) - && executedByUuid.equals(that.executedByUuid) - && executedTimestamp == that.executedTimestamp; - } - - return false; - } - - @Override public int hashCode() { - int result = measurements.hashCode(); - result = result * 37 + benchmarkName.hashCode(); - result = result * 37 + executedByUuid.hashCode(); - result = result * 37 + (int) ((executedTimestamp >> 32) ^ executedTimestamp); - return result; - } - - @Override public String toString() { - return measurements.toString(); - } - - private Run() {} // for GWT Serialization -} diff --git a/src/com/google/caliper/Runner.java b/src/com/google/caliper/Runner.java deleted file mode 100644 index e359df8..0000000 --- a/src/com/google/caliper/Runner.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import com.google.caliper.UserException.ExceptionFromUserCodeException; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import com.google.common.collect.ObjectArrays; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.UUID; - -/** - * Creates, executes and reports benchmark runs. - */ -public final class Runner { - - /** Command line arguments to the process */ - private Arguments arguments; - private ScenarioSelection scenarioSelection; - - /** - * Returns the UUID of the executing host. Multiple runs by the same user on - * the same machine should yield the same result. - */ - private String getExecutedByUuid() { - try { - File dotCaliperRc = new File(System.getProperty("user.home"), ".caliperrc"); - Properties properties = new Properties(); - if (dotCaliperRc.exists()) { - properties.load(new FileInputStream(dotCaliperRc)); - } - - String userUuid = properties.getProperty("userUuid"); - if (userUuid == null) { - userUuid = UUID.randomUUID().toString(); - properties.setProperty("userUuid", userUuid); - properties.store(new FileOutputStream(dotCaliperRc), ""); - } - - return userUuid; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void run(String... args) { - this.arguments = Arguments.parse(args); - this.scenarioSelection = new ScenarioSelection(arguments); - Run run = runOutOfProcess(); - new ConsoleReport(run).displayResults(); - postResults(run); - } - - private void postResults(Run run) { - String postHost = arguments.getPostHost(); - if ("none".equals(postHost)) { - return; - } - - try { - URL url = new URL(postHost + run.getExecutedByUuid() + "/" + run.getBenchmarkName()); - HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setDoOutput(true); - Xml.runToXml(run, urlConnection.getOutputStream()); - if (urlConnection.getResponseCode() == 200) { - System.out.println(""); - System.out.println("View current and previous benchmark results online:"); - System.out.println(" " + url); - return; - } - - System.out.println("Posting to " + postHost + " failed: " - + urlConnection.getResponseMessage()); - BufferedReader reader = new BufferedReader( - new InputStreamReader(urlConnection.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private double executeForked(Scenario scenario) { - ProcessBuilder builder = new ProcessBuilder(); - List<String> command = builder.command(); - command.addAll(Arrays.asList(scenario.getVariables().get(Scenario.VM_KEY).split("\\s+"))); - command.add("-cp"); - command.add(System.getProperty("java.class.path")); - command.add(InProcessRunner.class.getName()); - command.add("--warmupMillis"); - command.add(String.valueOf(arguments.getWarmupMillis())); - command.add("--runMillis"); - command.add(String.valueOf(arguments.getRunMillis())); - for (Entry<String, String> entry : scenario.getParameters().entrySet()) { - command.add("-D" + entry.getKey() + "=" + entry.getValue()); - } - command.add(arguments.getSuiteClassName()); - - BufferedReader reader = null; - try { - builder.redirectErrorStream(true); - builder.directory(new File(System.getProperty("user.dir"))); - Process process = builder.start(); - - reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - String firstLine = reader.readLine(); - Double nanosPerTrial = null; - try { - nanosPerTrial = Double.valueOf(firstLine); - } catch (NumberFormatException ignore) { - } - - String anotherLine = reader.readLine(); - if (nanosPerTrial != null && anotherLine == null) { - return nanosPerTrial; - } - - String message = "Failed to execute " + command; - System.err.println(message); - System.err.println(" " + firstLine); - do { - System.err.println(" " + anotherLine); - } while ((anotherLine = reader.readLine()) != null); - throw new ConfigurationException(message); - } catch (IOException e) { - throw new ConfigurationException(e); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ignored) { - } - } - } - } - - // TODO: check if this is platform-independent - @SuppressWarnings("HardcodedLineSeparator") - private static final String RETURN = "\r"; - - private Run runOutOfProcess() { - String executedByUuid = getExecutedByUuid(); - Date executedDate = new Date(); - Builder<Scenario, Double> resultsBuilder = ImmutableMap.builder(); - - try { - List<Scenario> scenarios = scenarioSelection.select(); - int i = 0; - for (Scenario scenario : scenarios) { - beforeMeasurement(i++, scenarios.size(), scenario); - double nanosPerTrial = executeForked(scenario); - afterMeasurement(nanosPerTrial); - resultsBuilder.put(scenario, nanosPerTrial); - } - - // blat out our progress bar - System.out.print(RETURN); - for (int j = 0; j < 80; j++) { - System.out.print(" "); - } - System.out.print(RETURN); - - return new Run(resultsBuilder.build(), arguments.getSuiteClassName(), executedByUuid, executedDate); - } catch (Exception e) { - throw new ExceptionFromUserCodeException(e); - } - } - - private void beforeMeasurement(int index, int total, Scenario scenario) { - double percentDone = (double) index / total; - int runStringLength = 63; // so the total line length is 80 - String runString = String.valueOf(scenario); - if (runString.length() > runStringLength) { - runString = runString.substring(0, runStringLength); - } - System.out.printf(RETURN + "%2.0f%% %-" + runStringLength + "s", - percentDone * 100, runString); - } - - private void afterMeasurement(double nanosPerTrial) { - System.out.printf(" %10.0fns", nanosPerTrial); - } - - public static void main(String... args) { - try { - new Runner().run(args); - } catch (UserException e) { - e.display(); - System.exit(1); - } - } - - public static void main(Class<? extends Benchmark> suite, String... args) { - main(ObjectArrays.concat(args, suite.getName())); - } -} diff --git a/src/com/google/caliper/Scenario.java b/src/com/google/caliper/Scenario.java deleted file mode 100644 index 3fd06e4..0000000 --- a/src/com/google/caliper/Scenario.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -/** - * A configured benchmark. - * - * <p>Gwt-safe. - */ -public final class Scenario - implements Serializable /* for GWT */ { - - static final String VM_KEY = "vm"; - - /** - * The subset of variable names that are managed by the system. It is an error - * to create a parameter with the same name as one of these variables. - */ - static final Set<String> SYSTEM_VARIABLES = new HashSet<String>(Arrays.asList(VM_KEY)); - - private /*final*/ Map<String, String> variables; - - public Scenario(Map<String, String> variables) { - this.variables = new LinkedHashMap<String, String>(variables); - } - - public Map<String, String> getVariables() { - return variables; - } - - /** - * Returns the user-specified parameters. This is the (possibly-empty) set of - * variables that may be varied from scenario to scenario in the same - * environment. - */ - public Map<String, String> getParameters() { - Map<String, String> result = new LinkedHashMap<String, String>(); - for (Map.Entry<String, String> entry : variables.entrySet()) { - if (!SYSTEM_VARIABLES.contains(entry.getKey())) { - result.put(entry.getKey(), entry.getValue()); - } - } - return result; - } - - @Override public boolean equals(Object o) { - return o instanceof Scenario - && ((Scenario) o).getVariables().equals(variables); - } - - @Override public int hashCode() { - return variables.hashCode(); - } - - @Override public String toString() { - return "Scenario" + variables; - } - - private Scenario() {} // for GWT -} diff --git a/src/com/google/caliper/ScenarioSelection.java b/src/com/google/caliper/ScenarioSelection.java deleted file mode 100644 index 7814818..0000000 --- a/src/com/google/caliper/ScenarioSelection.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2010 Google 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.google.caliper; - -import com.google.caliper.UserException.AbstractBenchmarkException; -import com.google.caliper.UserException.DoesntImplementBenchmarkException; -import com.google.caliper.UserException.ExceptionFromUserCodeException; -import com.google.caliper.UserException.NoParameterlessConstructorException; -import com.google.caliper.UserException.NoSuchClassException; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * Figures out which scenarios to benchmark given a benchmark suite, set of user - * parameters, and set of user VMs. - */ -public final class ScenarioSelection { - - private final String suiteClassName; - private final Multimap<String, String> userParameters; - private final Set<String> userVms; - - private Benchmark suite; - - /** Effective parameters to run in the benchmark. */ - private final Multimap<String, String> parameters = LinkedHashMultimap.create(); - - public ScenarioSelection(Arguments arguments) { - this(arguments.getSuiteClassName(), arguments.getUserParameters(), arguments.getUserVms()); - } - - public ScenarioSelection(String suiteClassName, - Multimap<String, String> userParameters, Set<String> userVms) { - this.suiteClassName = suiteClassName; - this.userParameters = userParameters; - this.userVms = userVms; - } - - /** - * Returns the selected scenarios for this benchmark. - */ - public List<Scenario> select() { - prepareSuite(); - prepareParameters(); - return createScenarios(); - } - - public TimedRunnable createBenchmark(Scenario scenario) { - return suite.createBenchmark(scenario.getParameters()); - } - - private void prepareSuite() { - Class<?> benchmarkClass; - try { - benchmarkClass = getClassByName(suiteClassName); - } catch (ExceptionInInitializerError e) { - throw new ExceptionFromUserCodeException(e.getCause()); - } catch (ClassNotFoundException ignored) { - throw new NoSuchClassException(suiteClassName); - } - - Object s; - try { - Constructor<?> constructor = benchmarkClass.getDeclaredConstructor(); - constructor.setAccessible(true); - s = constructor.newInstance(); - } catch (InstantiationException ignore) { - throw new AbstractBenchmarkException(benchmarkClass); - } catch (NoSuchMethodException ignore) { - throw new NoParameterlessConstructorException(benchmarkClass); - } catch (IllegalAccessException impossible) { - throw new AssertionError(impossible); // shouldn't happen since we setAccessible(true) - } catch (InvocationTargetException e) { - throw new ExceptionFromUserCodeException(e.getCause()); - } - - if (s instanceof Benchmark) { - this.suite = (Benchmark) s; - } else { - throw new DoesntImplementBenchmarkException(benchmarkClass); - } - } - - private static Class<?> getClassByName(String className) throws ClassNotFoundException { - try { - return Class.forName(className); - } catch (ClassNotFoundException ignored) { - // try replacing the last dot with a $, in case that helps - // example: tutorial.Tutorial.Benchmark1 becomes tutorial.Tutorial$Benchmark1 - // amusingly, the $ character means three different things in this one line alone - String newName = className.replaceFirst("\\.([^.]+)$", "\\$$1"); - return Class.forName(newName); - } - } - - private void prepareParameters() { - for (String key : suite.parameterNames()) { - // first check if the user has specified values - Collection<String> userValues = userParameters.get(key); - if (!userValues.isEmpty()) { - parameters.putAll(key, userValues); - // TODO: type convert 'em to validate? - - } else { // otherwise use the default values from the suite - Set<String> values = suite.parameterValues(key); - if (values.isEmpty()) { - throw new ConfigurationException(key + " has no values"); - } - parameters.putAll(key, values); - } - } - } - - private ImmutableSet<String> defaultVms() { - return "Dalvik".equals(System.getProperty("java.vm.name")) - ? ImmutableSet.of("dalvikvm") - : ImmutableSet.of("java"); - } - - /** - * Returns a complete set of scenarios with every combination of values and - * benchmark classes. - */ - private List<Scenario> createScenarios() { - List<ScenarioBuilder> builders = new ArrayList<ScenarioBuilder>(); - - // create scenarios for each VM - Set<String> vms = userVms.isEmpty() - ? defaultVms() - : userVms; - for (String vm : vms) { - ScenarioBuilder scenarioBuilder = new ScenarioBuilder(); - scenarioBuilder.parameters.put(Scenario.VM_KEY, vm); - builders.add(scenarioBuilder); - } - - for (Entry<String, Collection<String>> parameter : parameters.asMap().entrySet()) { - Iterator<String> values = parameter.getValue().iterator(); - if (!values.hasNext()) { - throw new ConfigurationException("Not enough values for " + parameter); - } - - String key = parameter.getKey(); - - String firstValue = values.next(); - for (ScenarioBuilder builder : builders) { - builder.parameters.put(key, firstValue); - } - - // multiply the size of the specs by the number of alternate values - int size = builders.size(); - while (values.hasNext()) { - String alternate = values.next(); - for (int s = 0; s < size; s++) { - ScenarioBuilder copy = builders.get(s).copy(); - copy.parameters.put(key, alternate); - builders.add(copy); - } - } - } - - List<Scenario> result = new ArrayList<Scenario>(); - for (ScenarioBuilder builder : builders) { - result.add(builder.build()); - } - - return result; - } - - private static class ScenarioBuilder { - final Map<String, String> parameters = new LinkedHashMap<String, String>(); - - ScenarioBuilder copy() { - ScenarioBuilder result = new ScenarioBuilder(); - result.parameters.putAll(parameters); - return result; - } - - public Scenario build() { - return new Scenario(parameters); - } - } -} diff --git a/src/com/google/caliper/SimpleBenchmark.java b/src/com/google/caliper/SimpleBenchmark.java deleted file mode 100644 index 31ff6c9..0000000 --- a/src/com/google/caliper/SimpleBenchmark.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import com.google.caliper.UserException.ExceptionFromUserCodeException; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -/** - * A convenience class for implementing benchmarks in plain code. - * Implementing classes must have a no-arguments constructor. - * - * <h3>Benchmarks</h3> - * The benchmarks of a suite are defined by . They may be - * static. They are not permitted to take parameters . . .. - * - * <h3>Parameters</h3> - * Implementing classes may be configured using parameters. Each parameter is a - * property of a benchmark, plus the default values that fulfill it. Parameters - * are specified by annotated fields: - * <pre> - * {@literal @}Param int length; - * </pre> - * The available values for a parameter are specified by another field with the - * same name plus the {@code Values} suffix. The type of this field must be an - * {@code Iterable} of the parameter's type. - * <pre> - * Iterable<Integer> lengthValues = Arrays.asList(10, 100, 1000, 10000); - * </pre> - * Alternatively, the available values may be specified with a method. The - * method's name follows the same naming convention and returns the same type. - * Such methods may not accept parameters of their own. - * <pre> - * Iterable<Integer> lengthValues() { - * return Arrays.asList(10, 100, 1000, 10000); - * } - * </pre> - */ -public abstract class SimpleBenchmark implements Benchmark { - - private static final Class<?>[] ARGUMENT_TYPES = { int.class }; - - private final Map<String, Parameter<?>> parameters; - private final Map<String, Method> methods; - - protected SimpleBenchmark() { - parameters = Parameter.forClass(getClass()); - methods = createTimedMethods(); - - if (methods.isEmpty()) { - throw new ConfigurationException( - "No benchmarks defined in " + getClass().getName()); - } - } - - protected void setUp() throws Exception {} - - public Set<String> parameterNames() { - return ImmutableSet.<String>builder() - .add("benchmark") - .addAll(parameters.keySet()) - .build(); - } - - public Set<String> parameterValues(String parameterName) { - if ("benchmark".equals(parameterName)) { - return methods.keySet(); - } - - Parameter<?> parameter = parameters.get(parameterName); - if (parameter == null) { - throw new IllegalArgumentException(); - } - try { - Collection<?> values = parameter.values(); - - ImmutableSet.Builder<String> result = ImmutableSet.builder(); - for (Object value : values) { - result.add(String.valueOf(value)); - } - return result.build(); - } catch (Exception e) { - throw new ExceptionFromUserCodeException(e); - } - } - - public TimedRunnable createBenchmark(Map<String, String> parameterValues) { - if (!parameterNames().equals(parameterValues.keySet())) { - throw new IllegalArgumentException("Invalid parameters specified. Expected " - + parameterNames() + " but was " + parameterValues.keySet()); - } - - try { - @SuppressWarnings({"ClassNewInstance"}) // can throw any Exception, so we catch all Exceptions - final SimpleBenchmark copyOfSelf = getClass().newInstance(); - final Method method = methods.get(parameterValues.get("benchmark")); - - for (Map.Entry<String, String> entry : parameterValues.entrySet()) { - String parameterName = entry.getKey(); - if ("benchmark".equals(parameterName)) { - continue; - } - - Parameter<?> parameter = parameters.get(parameterName); - Object value = TypeConverter.fromString(entry.getValue(), parameter.getType()); - parameter.set(copyOfSelf, value); - } - copyOfSelf.setUp(); - - return new TimedRunnable() { - public Object run(int reps) throws Exception { - return method.invoke(copyOfSelf, reps); - } - }; - - } catch (Exception e) { - throw new ExceptionFromUserCodeException(e); - } - } - - /** - * Returns a spec for each benchmark defined in the specified class. The - * returned specs have no parameter values; those must be added separately. - */ - private Map<String, Method> createTimedMethods() { - ImmutableMap.Builder<String, Method> result = ImmutableMap.builder(); - for (Method method : getClass().getDeclaredMethods()) { - int modifiers = method.getModifiers(); - if (!method.getName().startsWith("time")) { - continue; - } - - if (!Modifier.isPublic(modifiers) - || Modifier.isStatic(modifiers) - || Modifier.isAbstract(modifiers) - || !Arrays.equals(method.getParameterTypes(), ARGUMENT_TYPES)) { - throw new ConfigurationException("Timed methods must be public, " - + "non-static, non-abstract and take a single int parameter. " - + "But " + method + " violates these requirements."); - } - - result.put(method.getName().substring(4), method); - } - - return result.build(); - } -}
\ No newline at end of file diff --git a/src/com/google/caliper/TimedRunnable.java b/src/com/google/caliper/TimedRunnable.java deleted file mode 100644 index d1f9a6c..0000000 --- a/src/com/google/caliper/TimedRunnable.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (C) 2009 Google 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.google.caliper; - -public interface TimedRunnable { - - /** - * Runs the benchmark through {@code trials} iterations. - * - * @return any object or null. Benchmark implementors may keep an accumulating - * value to prevent the runtime from optimizing away the code under test. - * Such an accumulator value can be returned here. - */ - Object run(int reps) throws Exception; -} diff --git a/src/com/google/caliper/TypeConverter.java b/src/com/google/caliper/TypeConverter.java deleted file mode 100644 index 29d00ea..0000000 --- a/src/com/google/caliper/TypeConverter.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (C) 2009 Google 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.google.caliper; - -import com.google.common.collect.ImmutableMap; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.Map; - -/** - * Convert objects to and from Strings. - */ -final class TypeConverter { - private TypeConverter() {} - - public static Object fromString(String value, Type type) { - Class<?> c = wrap((Class<?>) type); - try { - Method m = c.getMethod("valueOf", String.class); - return m.invoke(null, value); - } catch (Exception e) { - throw new UnsupportedOperationException( - "Cannot convert " + value + " of type " + type, e); - } - } - - // safe because both Long.class and long.class are of type Class<Long> - @SuppressWarnings("unchecked") - private static <T> Class<T> wrap(Class<T> c) { - return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c; - } - - private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS - = new ImmutableMap.Builder<Class<?>, Class<?>>() - .put(boolean.class, Boolean.class) - .put(byte.class, Byte.class) - .put(char.class, Character.class) - .put(double.class, Double.class) - .put(float.class, Float.class) - .put(int.class, Integer.class) - .put(long.class, Long.class) - .put(short.class, Short.class) - .put(void.class, Void.class) - .build(); -} diff --git a/src/com/google/caliper/UserException.java b/src/com/google/caliper/UserException.java deleted file mode 100644 index 66fb8e3..0000000 --- a/src/com/google/caliper/UserException.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2009 Google 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.google.caliper; - -import java.util.Arrays; - -/** - * Signifies a problem that should be explained in user-friendly terms on the command line, without - * a confusing stack trace, and optionally followed by a usage summary. - */ -@SuppressWarnings("serial") // never going to serialize these... right? -public abstract class UserException extends RuntimeException { - protected final String error; - - protected UserException(String error) { - this.error = error; - } - - public abstract void display(); - - // - - - - - - public abstract static class ErrorInUsageException extends UserException { - protected ErrorInUsageException(String error) { - super(error); - } - - @Override public void display() { - if (error != null) { - System.err.println("Error: " + error); - } - Arguments.printUsage(); - } - } - - public abstract static class ErrorInUserCodeException extends UserException { - private final String remedy; - - protected ErrorInUserCodeException(String error, String remedy) { - super(error); - this.remedy = remedy; - } - - @Override public void display() { - System.err.println("Error: " + error); - System.err.println("Typical Remedy: " + remedy); - } - } - - // - - - - - - // Not technically an error, but works nicely this way anyway - public static class DisplayUsageException extends ErrorInUsageException { - public DisplayUsageException() { - super(null); - } - } - - public static class UnrecognizedOptionException extends ErrorInUsageException { - public UnrecognizedOptionException(String arg) { - super("Argument not recognized: " + arg); - } - } - - public static class NoBenchmarkClassException extends ErrorInUsageException { - public NoBenchmarkClassException() { - super("No benchmark class specified."); - } - } - - public static class MultipleBenchmarkClassesException extends ErrorInUsageException { - public MultipleBenchmarkClassesException(String a, String b) { - super("Multiple benchmark classes specified: " + Arrays.asList(a, b)); - } - } - - public static class MalformedParameterException extends ErrorInUsageException { - public MalformedParameterException(String arg) { - super("Malformed parameter: " + arg); - } - } - - public static class CantCustomizeInProcessVmException extends ErrorInUsageException { - public CantCustomizeInProcessVmException() { - super("Can't customize VM when running in process."); - } - } - - public static class NoSuchClassException extends ErrorInUsageException { - public NoSuchClassException(String name) { - super("No class named [" + name + "] was found (check CLASSPATH)."); - } - } - - - public static class AbstractBenchmarkException extends ErrorInUserCodeException { - public AbstractBenchmarkException(Class<?> specifiedClass) { - super("Class [" + specifiedClass.getName() + "] is abstract.", "Specify a concrete class."); - } - } - - public static class NoParameterlessConstructorException extends ErrorInUserCodeException { - public NoParameterlessConstructorException(Class<?> specifiedClass) { - super("Class [" + specifiedClass.getName() + "] has no parameterless constructor.", - "Remove all constructors or add a parameterless constructor."); - } - } - - public static class DoesntImplementBenchmarkException extends ErrorInUserCodeException { - public DoesntImplementBenchmarkException(Class<?> specifiedClass) { - super("Class [" + specifiedClass + "] does not implement the " + Benchmark.class.getName() - + " interface.", "Add 'extends " + SimpleBenchmark.class + "' to the class declaration."); - } - } - - // TODO: should remove the caliper stack frames.... - public static class ExceptionFromUserCodeException extends UserException { - public ExceptionFromUserCodeException(Throwable t) { - super("An exception was thrown from the benchmark code."); - initCause(t); - } - @Override public void display() { - System.err.println(error); - getCause().printStackTrace(System.err); - } - } -} diff --git a/src/com/google/caliper/Xml.java b/src/com/google/caliper/Xml.java deleted file mode 100644 index f7cfafc..0000000 --- a/src/com/google/caliper/Xml.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Copyright (C) 2009 Google 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.google.caliper; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import java.io.InputStream; -import java.io.OutputStream; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; - -public final class Xml { - private static final String DATE_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssz"; - - /** - * Encodes this result as XML to the specified stream. This XML can be parsed - * with {@link #runFromXml(InputStream)}. Sample output: - * <pre>{@code - * <result benchmark="examples.FooBenchmark" - * executedBy="A0:1F:CAFE:BABE" - * executedTimestamp="2010-01-05T11:08:15PST"> - * <scenario bar="15" foo="A" vm="dalvikvm">1200.1</scenario> - * <scenario bar="15" foo="B" vm="dalvikvm">1100.2</scenario> - * </result> - * }</pre> - */ - public static void runToXml(Run run, OutputStream out) { - // BEGIN android-removed - // we don't have DOM level 3 on Android yet - // try { - // Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - // Element result = doc.createElement("result"); - // doc.appendChild(result); - // - // result.setAttribute("benchmark", run.getBenchmarkName()); - // result.setAttribute("executedBy", run.getExecutedByUuid()); - // String executedTimestampString = new SimpleDateFormat(DATE_FORMAT_STRING) - // .format(run.getExecutedTimestamp()); - // result.setAttribute("executedTimestamp", executedTimestampString); - // - // for (Map.Entry<Scenario, Double> entry : run.getMeasurements().entrySet()) { - // Element runElement = doc.createElement("scenario"); - // result.appendChild(runElement); - // - // Scenario scenario = entry.getKey(); - // for (Map.Entry<String, String> parameter : scenario.getVariables().entrySet()) { - // runElement.setAttribute(parameter.getKey(), parameter.getValue()); - // } - // runElement.setTextContent(String.valueOf(entry.getValue())); - // } - // - // TransformerFactory.newInstance().newTransformer() - // .transform(new DOMSource(doc), new StreamResult(out)); - // } catch (Exception e) { - // throw new IllegalStateException("Malformed XML document", e); - // } - // END android-removed - } - - /** - * Creates a result by decoding XML from the specified stream. The XML should - * be consistent with the format emitted by {@link #runToXml(Run, OutputStream)}. - */ - public static Run runFromXml(InputStream in) { - // BEGIN android-removed - // we don't have DOM level 3 on Android yet - throw new UnsupportedOperationException(); - // try { - // Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in); - // Element result = document.getDocumentElement(); - // - // String benchmarkName = result.getAttribute("benchmark"); - // String executedByUuid = result.getAttribute("executedBy"); - // String executedDateString = result.getAttribute("executedTimestamp"); - // Date executedDate = new SimpleDateFormat(DATE_FORMAT_STRING).parse(executedDateString); - // - // ImmutableMap.Builder<Scenario, Double> measurementsBuilder = ImmutableMap.builder(); - // for (Node node : childrenOf(result)) { - // Element scenarioElement = (Element) node; - // Scenario scenario = new Scenario(attributesOf(scenarioElement)); - // double measurement = Double.parseDouble(scenarioElement.getTextContent()); - // measurementsBuilder.put(scenario, measurement); - // } - // - // return new Run(measurementsBuilder.build(), benchmarkName, executedByUuid, executedDate); - // } catch (Exception e) { - // throw new IllegalStateException("Malformed XML document", e); - // } - // END android-removed - } - - private Xml() {} -} diff --git a/src/examples/ArraySortBenchmark.java b/src/examples/ArraySortBenchmark.java deleted file mode 100644 index f42390f..0000000 --- a/src/examples/ArraySortBenchmark.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import java.util.Arrays; -import java.util.Random; - -/** - * Measures sorting on different distributions of integers. - */ -public class ArraySortBenchmark extends SimpleBenchmark { - - @Param({"10", "100", "1000", "10000"}) private int length; - - @Param private Distribution distribution; - - private int[] values; - private int[] copy; - - @Override protected void setUp() throws Exception { - values = distribution.create(length); - copy = new int[length]; - } - - public void timeSort(int reps) { - for (int i = 0; i < reps; i++) { - System.arraycopy(values, 0, copy, 0, values.length); - Arrays.sort(copy); - } - } - - public enum Distribution { - SAWTOOTH { - @Override - int[] create(int length) { - int[] result = new int[length]; - for (int i = 0; i < length; i += 5) { - result[i] = 0; - result[i + 1] = 1; - result[i + 2] = 2; - result[i + 3] = 3; - result[i + 4] = 4; - } - return result; - } - }, - INCREASING { - @Override - int[] create(int length) { - int[] result = new int[length]; - for (int i = 0; i < length; i++) { - result[i] = i; - } - return result; - } - }, - DECREASING { - @Override - int[] create(int length) { - int[] result = new int[length]; - for (int i = 0; i < length; i++) { - result[i] = length - i; - } - return result; - } - }, - RANDOM { - @Override - int[] create(int length) { - Random random = new Random(); - int[] result = new int[length]; - for (int i = 0; i < length; i++) { - result[i] = random.nextInt(); - } - return result; - } - }; - - abstract int[] create(int length); - } - - public static void main(String[] args) throws Exception { - Runner.main(ArraySortBenchmark.class, args); - } -} diff --git a/src/examples/BoxedDoubleToStringBenchmark.java b/src/examples/BoxedDoubleToStringBenchmark.java deleted file mode 100644 index 22cb28e..0000000 --- a/src/examples/BoxedDoubleToStringBenchmark.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import com.google.common.collect.ImmutableList; -import java.util.Collection; - -/** - * Measures the various ways the JDK converts boxed Doubles to Strings. - */ -public class BoxedDoubleToStringBenchmark extends SimpleBenchmark { - - @Param private Double d; - - // Expressing these as strings in the annotation parameter would be annoying - // (and maybe not possible?) - public static final Collection<Double> dValues = ImmutableList.of( - Math.PI, - -0.0d, - Double.NEGATIVE_INFINITY, - Double.NaN - ); - - public int timeStringFormat(int reps) { - Double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += String.format("%f", value).length(); - } - return dummy; - } - - public int timeToString(int reps) { - Double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += value.toString().length(); - } - return dummy; - } - - public int timeStringValueOf(int reps) { - Double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += String.valueOf(value).length(); - } - return dummy; - } - - public int timeQuoteTrick(int reps) { - Double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += ("" + value).length(); - } - return dummy; - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(BoxedDoubleToStringBenchmark.class, args); - } -} diff --git a/src/examples/CharacterBenchmark.java b/src/examples/CharacterBenchmark.java deleted file mode 100644 index 1e013af..0000000 --- a/src/examples/CharacterBenchmark.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * Tests various Character methods, intended for testing multiple - * implementations against each other. - */ -public class CharacterBenchmark extends SimpleBenchmark { - - @Param private CharacterSet characterSet; - - @Param private Overload overload; - - private char[] chars; - - @Override protected void setUp() throws Exception { - this.chars = characterSet.chars; - } - - public enum Overload { CHAR, INT } - - public enum CharacterSet { - ASCII(128), - UNICODE(65536); - final char[] chars; - CharacterSet(int size) { - this.chars = new char[65536]; - for (int i = 0; i < 65536; ++i) { - chars[i] = (char) (i % size); - } - } - } - - // A fake benchmark to give us a baseline. - public boolean timeIsSpace(int reps) { - boolean dummy = false; - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - dummy ^= ((char) ch == ' '); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - dummy ^= (ch == ' '); - } - } - } - return dummy; - } - - public void timeDigit(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.digit(chars[ch], 10); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.digit((int) chars[ch], 10); - } - } - } - } - - public void timeGetNumericValue(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.getNumericValue(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.getNumericValue((int) chars[ch]); - } - } - } - } - - public void timeIsDigit(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isDigit(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isDigit((int) chars[ch]); - } - } - } - } - - public void timeIsIdentifierIgnorable(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isIdentifierIgnorable(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isIdentifierIgnorable((int) chars[ch]); - } - } - } - } - - public void timeIsJavaIdentifierPart(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isJavaIdentifierPart(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isJavaIdentifierPart((int) chars[ch]); - } - } - } - } - - public void timeIsJavaIdentifierStart(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isJavaIdentifierStart(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isJavaIdentifierStart((int) chars[ch]); - } - } - } - } - - public void timeIsLetter(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isLetter(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isLetter((int) chars[ch]); - } - } - } - } - - public void timeIsLetterOrDigit(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isLetterOrDigit(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isLetterOrDigit((int) chars[ch]); - } - } - } - } - - public void timeIsLowerCase(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isLowerCase(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isLowerCase((int) chars[ch]); - } - } - } - } - - public void timeIsSpaceChar(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isSpaceChar(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isSpaceChar((int) chars[ch]); - } - } - } - } - - public void timeIsUpperCase(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isUpperCase(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isUpperCase((int) chars[ch]); - } - } - } - } - - public void timeIsWhitespace(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isWhitespace(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.isWhitespace((int) chars[ch]); - } - } - } - } - - public void timeToLowerCase(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.toLowerCase(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.toLowerCase((int) chars[ch]); - } - } - } - } - - public void timeToUpperCase(int reps) { - if (overload == Overload.CHAR) { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.toUpperCase(chars[ch]); - } - } - } else { - for (int i = 0; i < reps; ++i) { - for (int ch = 0; ch < 65536; ++ch) { - Character.toUpperCase((int) chars[ch]); - } - } - } - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(CharacterBenchmark.class, args); - } -} diff --git a/src/examples/EnumSetContainsBenchmark.java b/src/examples/EnumSetContainsBenchmark.java deleted file mode 100644 index b232514..0000000 --- a/src/examples/EnumSetContainsBenchmark.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import java.util.EnumSet; -import java.util.Set; - -/** - * Measures EnumSet#contains(). - */ -public class EnumSetContainsBenchmark extends SimpleBenchmark { - - @Param private SetMaker setMaker; - - public enum SetMaker { - ENUM_SET { - @Override Set<?> newSet() { - return EnumSet.allOf(RegularSize.class); - } - @Override Object[] testValues() { - return new Object[] { RegularSize.E1, RegularSize.E2, RegularSize.E20, - RegularSize.E39, RegularSize.E40, "A", LargeSize.E40, null }; - } - }, - LARGE_ENUM_SET { - @Override Set<?> newSet() { - return EnumSet.allOf(LargeSize.class); - } - @Override Object[] testValues() { - return new Object[] { LargeSize.E1, LargeSize.E63, LargeSize.E64, - LargeSize.E65, LargeSize.E140, "A", RegularSize.E40, null }; - } - }; - - abstract Set<?> newSet(); - abstract Object[] testValues(); - } - - private enum RegularSize { - E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, - E18, E19, E20, E21, E22, E23, E24, E25, E26, E27, E28, E29, E30, E31, E32, - E33, E34, E35, E36, E37, E38, E39, E40, - } - - private enum LargeSize { - E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, E15, E16, E17, - E18, E19, E20, E21, E22, E23, E24, E25, E26, E27, E28, E29, E30, E31, E32, - E33, E34, E35, E36, E37, E38, E39, E40, E41, E42, E43, E44, E45, E46, E47, - E48, E49, E50, E51, E52, E53, E54, E55, E56, E57, E58, E59, E60, E61, E62, - E63, E64, E65, E66, E67, E68, E69, E70, E71, E72, E73, E74, E75, E76, E77, - E78, E79, E80, E81, E82, E83, E84, E85, E86, E87, E88, E89, E90, E91, E92, - E93, E94, E95, E96, E97, E98, E99, E100, E101, E102, E103, E104, E105, E106, - E107, E108, E109, E110, E111, E112, E113, E114, E115, E116, E117, E118, - E119, E120, E121, E122, E123, E124, E125, E126, E127, E128, E129, E130, - E131, E132, E133, E134, E135, E136, E137, E138, E139, E140, - } - - private Set<?> set; - private Object[] testValues; - - @Override protected void setUp() { - this.set = setMaker.newSet(); - this.testValues = setMaker.testValues(); - } - - public void timeContains(int reps) { - for (int i = 0; i < reps; i++) { - set.contains(testValues[i % testValues.length]); - } - } - - public static void main(String[] args) throws Exception { - Runner.main(EnumSetContainsBenchmark.class, args); - } -} diff --git a/src/examples/ExpensiveObjectsBenchmark.java b/src/examples/ExpensiveObjectsBenchmark.java deleted file mode 100644 index ebff8e6..0000000 --- a/src/examples/ExpensiveObjectsBenchmark.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.Locale; - -/** - * Benchmarks creation and cloning various expensive objects. - */ -@SuppressWarnings({"ResultOfObjectAllocationIgnored"}) // TODO: should fix! -public class ExpensiveObjectsBenchmark extends SimpleBenchmark { - public void timeNewDecimalFormatSymbols(int reps) { - for (int i = 0; i < reps; ++i) { - new DecimalFormatSymbols(Locale.US); - } - } - - public void timeClonedDecimalFormatSymbols(int reps) { - DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); - for (int i = 0; i < reps; ++i) { - dfs.clone(); - } - } - - public void timeNewNumberFormat(int reps) { - for (int i = 0; i < reps; ++i) { - NumberFormat.getInstance(Locale.US); - } - } - - public void timeClonedNumberFormat(int reps) { - NumberFormat nf = NumberFormat.getInstance(Locale.US); - for (int i = 0; i < reps; ++i) { - nf.clone(); - } - } - - public void timeNewSimpleDateFormat(int reps) { - for (int i = 0; i < reps; ++i) { - new SimpleDateFormat(); - } - } - - public void timeClonedSimpleDateFormat(int reps) { - SimpleDateFormat sdf = new SimpleDateFormat(); - for (int i = 0; i < reps; ++i) { - sdf.clone(); - } - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(ExpensiveObjectsBenchmark.class, args); - } -} diff --git a/src/examples/FormatterBenchmark.java b/src/examples/FormatterBenchmark.java deleted file mode 100644 index b4a0541..0000000 --- a/src/examples/FormatterBenchmark.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import java.util.Formatter; - -/** - * Compares Formatter against hand-written StringBuilder code. - */ -public class FormatterBenchmark extends SimpleBenchmark { - public void timeFormatter_NoFormatting(int reps) { - for (int i = 0; i < reps; i++) { - Formatter f = new Formatter(); - f.format("this is a reasonably short string that doesn't actually need any formatting"); - } - } - - public void timeStringBuilder_NoFormatting(int reps) { - for (int i = 0; i < reps; i++) { - StringBuilder sb = new StringBuilder(); - sb.append("this is a reasonably short string that doesn't actually need any formatting"); - } - } - - public void timeFormatter_OneInt(int reps) { - for (int i = 0; i < reps; i++) { - Formatter f = new Formatter(); - f.format("this is a reasonably short string that has an int %d in it", i); - } - } - - public void timeStringBuilder_OneInt(int reps) { - for (int i = 0; i < reps; i++) { - StringBuilder sb = new StringBuilder(); - sb.append("this is a reasonably short string that has an int "); - sb.append(i); - sb.append(" in it"); - } - } - - public void timeFormatter_OneString(int reps) { - for (int i = 0; i < reps; i++) { - Formatter f = new Formatter(); - f.format("this is a reasonably short string that has a string %s in it", "hello"); - } - } - - public void timeStringBuilder_OneString(int reps) { - for (int i = 0; i < reps; i++) { - StringBuilder sb = new StringBuilder(); - sb.append("this is a reasonably short string that has a string "); - sb.append("hello"); - sb.append(" in it"); - } - } - - public static void main(String[] args) throws Exception { - Runner.main(FormatterBenchmark.class, args); - } -} diff --git a/src/examples/IntModBenchmark.java b/src/examples/IntModBenchmark.java deleted file mode 100644 index 55a119c..0000000 --- a/src/examples/IntModBenchmark.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * Measures several candidate implementations for mod(). - */ -@SuppressWarnings("SameParameterValue") -public class IntModBenchmark extends SimpleBenchmark { - private static final int M = (1 << 16) - 1; - - public int timeConditional(int reps) { - int dummy = 5; - for (int i = 0; i < reps; i++) { - dummy += Integer.MAX_VALUE + conditionalMod(dummy, M); - } - return dummy; - } - - private static int conditionalMod(int a, int m) { - int r = a % m; - return r < 0 ? r + m : r; - } - - public int timeDoubleRemainder(int reps) { - int dummy = 5; - for (int i = 0; i < reps; i++) { - dummy += Integer.MAX_VALUE + doubleRemainderMod(dummy, M); - } - return dummy; - } - - @SuppressWarnings("NumericCastThatLosesPrecision") // result of % by an int must be in int range - private static int doubleRemainderMod(int a, int m) { - return (int) ((a % m + (long) m) % m); - } - - public int timeRightShiftingMod(int reps) { - int dummy = 5; - for (int i = 0; i < reps; i++) { - dummy += Integer.MAX_VALUE + rightShiftingMod(dummy, M); - } - return dummy; - } - - @SuppressWarnings("NumericCastThatLosesPrecision") // must be in int range - private static int rightShiftingMod(int a, int m) { - long r = a % m; - return (int) (r + (r >> 63 & m)); - } - - public int timeLeftShiftingMod(int reps) { - int dummy = 5; - for (int i = 0; i < reps; i++) { - dummy += Integer.MAX_VALUE + leftShiftingMod(dummy, M); - } - return dummy; - } - - @SuppressWarnings("NumericCastThatLosesPrecision") // result of % by an int must be in int range - private static int leftShiftingMod(int a, int m) { - return (int) ((a + ((long) m << 32)) % m); - } - - public int timeWrongMod(int reps) { - int dummy = 5; - for (int i = 0; i < reps; i++) { - dummy += Integer.MAX_VALUE + dummy % M; - } - return dummy; - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(IntModBenchmark.class, args); - } -}
\ No newline at end of file diff --git a/src/examples/ListIterationBenchmark.java b/src/examples/ListIterationBenchmark.java deleted file mode 100644 index a8cfb05..0000000 --- a/src/examples/ListIterationBenchmark.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import java.util.AbstractList; -import java.util.List; - -/** - * Measures iterating through list elements. - */ -public class ListIterationBenchmark extends SimpleBenchmark { - - @Param({"0", "10", "100", "1000"}) - private int length; - - private List<Object> list; - private Object[] array; - - @Override protected void setUp() { - array = new Object[length]; - for (int i = 0; i < length; i++) { - array[i] = new Object(); - } - - list = new AbstractList<Object>() { - @Override public int size() { - return length; - } - - @Override public Object get(int i) { - return array[i]; - } - }; - } - - @SuppressWarnings({"UnusedDeclaration"}) // TODO: fix - public void timeListIteration(int reps) { - for (int i = 0; i < reps; i++) { - for (Object value : list) { - } - } - } - - @SuppressWarnings({"UnusedDeclaration"}) // TODO: fix - public void timeArrayIteration(int reps) { - for (int i = 0; i < reps; i++) { - for (Object value : array) { - } - } - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(ListIterationBenchmark.class, args); - } -}
\ No newline at end of file diff --git a/src/examples/LoopingBackwardsBenchmark.java b/src/examples/LoopingBackwardsBenchmark.java deleted file mode 100644 index e98e5fc..0000000 --- a/src/examples/LoopingBackwardsBenchmark.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * Testing the old canard that looping backwards is faster. - * - * @author Kevin Bourrillion - */ -public class LoopingBackwardsBenchmark extends SimpleBenchmark { - @Param({"2", "20", "2000", "20000000"}) int max; - - public int timeForwards(int reps) { - int dummy = 0; - for (int i = 0; i < reps; i++) { - for (int j = 0; j < max; j++) { - dummy += j; - } - } - return dummy; - } - - public int timeBackwards(int reps) { - int dummy = 0; - for (int i = 0; i < reps; i++) { - for (int j = max - 1; j >= 0; j--) { - dummy += j; - } - } - return dummy; - } - - public static void main(String[] args) throws Exception { - Runner.main(LoopingBackwardsBenchmark.class, args); - } -} diff --git a/src/examples/PrimitiveDoubleToStringBenchmark.java b/src/examples/PrimitiveDoubleToStringBenchmark.java deleted file mode 100644 index d49a53d..0000000 --- a/src/examples/PrimitiveDoubleToStringBenchmark.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import com.google.common.collect.ImmutableList; -import java.util.Collection; - -/** - * Measures the various ways the JDK converts primitive doubles to Strings. - */ -public class PrimitiveDoubleToStringBenchmark extends SimpleBenchmark { - - @Param private double d; - - public static final Collection<Double> dValues = ImmutableList.of( - Math.PI, - -0.0d, - Double.NEGATIVE_INFINITY, - Double.NaN - ); - - public int timeStringFormat(int reps) { - double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += String.format("%f", value).length(); - } - return dummy; - } - - public int timeToString(int reps) { - double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += ((Double) value).toString().length(); - } - return dummy; - } - - public int timeStringValueOf(int reps) { - double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy += String.valueOf(value).length(); - } - return dummy; - } - - public int timeQuoteTrick(int reps) { - double value = d; - int dummy = 0; - for (int i = 0; i < reps; i++) { - dummy = ("" + value).length(); - } - return dummy; - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(PrimitiveDoubleToStringBenchmark.class, args); - } -}
\ No newline at end of file diff --git a/src/examples/SetContainsBenchmark.java b/src/examples/SetContainsBenchmark.java deleted file mode 100644 index 4185d55..0000000 --- a/src/examples/SetContainsBenchmark.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import com.google.common.collect.ImmutableSet; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Random; -import java.util.Set; - -/** - * A microbenchmark that tests the performance of contains() on various Set - * implementations. - * - * @author Kevin Bourrillion - */ -public class SetContainsBenchmark extends SimpleBenchmark { - @Param private Impl impl; - - // So far, this is the best way to test various implementations - public enum Impl { - Hash { - @Override Set<Integer> create(Collection<Integer> contents) { - return new HashSet<Integer>(contents); - } - }, - LinkedHash { - @Override Set<Integer> create(Collection<Integer> contents) { - return new LinkedHashSet<Integer>(contents); - } - }, - UnmodHS { - @Override Set<Integer> create(Collection<Integer> contents) { - return Collections.unmodifiableSet(new HashSet<Integer>(contents)); - } - }, - SyncHS { - @Override Set<Integer> create(Collection<Integer> contents) { - return Collections.synchronizedSet(new HashSet<Integer>(contents)); - } - }, - - // Kind of cheating here -- Caliper just happens to bundle Google Collections so I'm testing - // this from it; this might not work at the command line since GC are jarjar'd for caliper.jar - Immutable { - @Override Set<Integer> create(Collection<Integer> contents) { - return ImmutableSet.copyOf(contents); - } - }; - - abstract Set<Integer> create(Collection<Integer> contents); - } - - @Param private int size; - public static final Collection<Integer> sizeValues = Arrays.asList( - (1<<2) - 1, - (1<<2), - (1<<6) - 1, - (1<<6), - (1<<10) - 1, - (1<<10), - (1<<14) - 1, - (1<<14), - (1<<18) - 1, - (1<<18) - ); - - // "" means no fixed seed - @Param("") private SpecialRandom random; - - // the following must be set during setUp - private Integer[] queries; - private Set<Integer> setToTest; - - // Queries are just sequential integers. Since the contents of the set were - // chosen randomly, this shouldn't cause any undue bias. - @Override public void setUp() { - this.queries = new Integer[size * 2]; - for (int i = 0; i < size * 2; i++) { - queries[i] = i; - } - Collections.shuffle(Arrays.asList(queries), random); - - setToTest = impl.create(createData()); - } - - private Collection<Integer> createData() { - Set<Integer> tempSet = new HashSet<Integer>(size * 3 / 2); - - // Choose 50% of the numbers between 0 and max to be in the set; thus we - // are measuring performance of contains() when there is a 50% hit rate - int max = size * 2; - while (tempSet.size() < size) { - tempSet.add(random.nextInt(max)); - } - return tempSet; - } - - public boolean timeContains(int reps) { - // Paranoia: acting on hearsay that accessing fields might be slow - // Should write a benchmark to test that! - Set<Integer> set = setToTest; - Integer[] queries = this.queries; - - // Allows us to use & instead of %, acting on hearsay that division operators (/%) are - // disproportionately expensive; should test this too! - int mask = Integer.highestOneBit(size * 2) - 1; - - boolean dummy = false; - for (int i = 0; i < reps; i++) { - dummy ^= set.contains(queries[i & mask]); - } - return dummy; - } - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(SetContainsBenchmark.class, args); - } - - - // Just an experiment with a slightly nicer way to create Randoms for benchies - - public static class SpecialRandom extends Random { - public static SpecialRandom valueOf(String s) { - return (s.length() == 0) - ? new SpecialRandom() - : new SpecialRandom(Long.parseLong(s)); - } - - private final boolean hasSeed; - private final long seed; - - public SpecialRandom() { - this.hasSeed = false; - this.seed = 0; - } - - public SpecialRandom(long seed) { - super(seed); - this.hasSeed = true; - this.seed = seed; - } - - @Override public String toString() { - return hasSeed ? "(seed:" + seed : "(default seed)"; - } - - private static final long serialVersionUID = 0; - } -} diff --git a/src/examples/StringBuilderBenchmark.java b/src/examples/StringBuilderBenchmark.java deleted file mode 100644 index 35e34f7..0000000 --- a/src/examples/StringBuilderBenchmark.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 examples; - -import com.google.caliper.Param; -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * Tests the performance of various StringBuilder methods. - */ -public class StringBuilderBenchmark extends SimpleBenchmark { - - @Param({"1", "10", "100"}) private int length; - - public void timeAppendBoolean(int reps) { - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(true); - } - } - } - - public void timeAppendChar(int reps) { - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append('c'); - } - } - } - - public void timeAppendCharArray(int reps) { - char[] chars = "chars".toCharArray(); - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(chars); - } - } - } - - public void timeAppendCharSequence(int reps) { - CharSequence cs = "chars"; - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(cs); - } - } - } - - public void timeAppendDouble(int reps) { - double d = 1.2; - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(d); - } - } - } - - public void timeAppendFloat(int reps) { - float f = 1.2f; - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(f); - } - } - } - - public void timeAppendInt(int reps) { - int n = 123; - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(n); - } - } - } - - public void timeAppendLong(int reps) { - long l = 123; - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(l); - } - } - } - - public void timeAppendObject(int reps) { - Object o = new Object(); - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(o); - } - } - } - - public void timeAppendString(int reps) { - String s = "chars"; - for (int i = 0; i < reps; ++i) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < length; ++j) { - sb.append(s); - } - } - } - - - // TODO: remove this from all examples when IDE plugins are ready - public static void main(String[] args) throws Exception { - Runner.main(StringBuilderBenchmark.class, args); - } -} diff --git a/src/scripts/caliper b/src/scripts/caliper deleted file mode 100644 index fb859a9..0000000 --- a/src/scripts/caliper +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# rough - -export PATH=$PATH:$JAVA_HOME/bin -base=`dirname $0` -exec java -cp $base/lib/caliper-@VERSION@.jar:$CLASSPATH com.google.caliper.Runner $* - diff --git a/src/test/BrokenNoOpBenchmark.java b/src/test/BrokenNoOpBenchmark.java deleted file mode 100644 index 95509fa..0000000 --- a/src/test/BrokenNoOpBenchmark.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2009 Google 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 test; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * This fails with a runtime out of range error. - */ -public class BrokenNoOpBenchmark extends SimpleBenchmark { - - public void timeNoOp(int reps) { - for (int i = 0; i < reps; i++) {} - } - - public static void main(String[] args) throws Exception { - Runner.main(BrokenNoOpBenchmark.class, args); - } -} diff --git a/src/test/BrokenSleepBenchmark.java b/src/test/BrokenSleepBenchmark.java deleted file mode 100644 index 964cf1a..0000000 --- a/src/test/BrokenSleepBenchmark.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2009 Google 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 test; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * Should fail with a measurement error. - */ -public class BrokenSleepBenchmark extends SimpleBenchmark { - // And look, IDEA tries to warn you - @SuppressWarnings({"UnusedDeclaration", "UnusedParameters"}) - public void timeSleepOneSecond(int reps) { - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } - } - - public static void main(String[] args) throws Exception { - Runner.main(BrokenSleepBenchmark.class, args); - } -} diff --git a/src/test/ErrorsInUserCodeTest.java b/src/test/ErrorsInUserCodeTest.java deleted file mode 100644 index dbb9f88..0000000 --- a/src/test/ErrorsInUserCodeTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 test; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; -import com.google.caliper.UserException.AbstractBenchmarkException; -import com.google.caliper.UserException.DoesntImplementBenchmarkException; -import com.google.caliper.UserException.ExceptionFromUserCodeException; -import com.google.caliper.UserException.NoParameterlessConstructorException; -import junit.framework.TestCase; - -/** - * Unit test covering common user mistakes. - * - * @author Kevin Bourrillion - */ -public class ErrorsInUserCodeTest extends TestCase { - private Runner runner; - - @Override protected void setUp() throws Exception { - runner = new Runner(); - } - - public void testDidntSubclassAnything() { - try { - runner.run(NotABenchmark.class.getName()); - fail(); - } catch (DoesntImplementBenchmarkException expected) { - } - } - - static class NotABenchmark { - public void timeSomething(int reps) { - fail("" + reps); - } - } - - - public void testAbstract() { - try { - runner.run(AbstractBenchmark.class.getName()); - fail(); - } catch (AbstractBenchmarkException expected) { - } - } - - abstract static class AbstractBenchmark extends SimpleBenchmark { - public void timeSomething(int reps) { - fail("" + reps); - } - } - - - public void testNoSuitableConstructor() { - try { - runner.run(BadConstructorBenchmark.class.getName()); - fail(); - } catch (NoParameterlessConstructorException expected) { - } - } - - static class BadConstructorBenchmark extends SimpleBenchmark { - BadConstructorBenchmark(String damnParam) { - fail(damnParam); - } - - public void timeSomething(int reps) { - fail("" + reps); - } - } - - - @SuppressWarnings("serial") - static class SomeUserException extends RuntimeException {} - - private static void throwSomeUserException() { - throw new SomeUserException(); - } - - - public void testExceptionInInit() { - try { - runner.run(ExceptionInInitBenchmark.class.getName()); - fail(); - } catch (ExceptionFromUserCodeException expected) { - } - } - - static class ExceptionInInitBenchmark extends SimpleBenchmark { - static { - throwSomeUserException(); - } - - public void timeSomething(int reps) { - fail("" + reps); - } - } - - public void testExceptionInConstructor() { - try { - runner.run(ExceptionInConstructorBenchmark.class.getName()); - fail(); - } catch (ExceptionFromUserCodeException expected) { - } - } - - static class ExceptionInConstructorBenchmark extends SimpleBenchmark { - ExceptionInConstructorBenchmark() { - throw new SomeUserException(); - } - - public void timeSomething(int reps) { - fail("" + reps); - } - } - - // TODO: enable - public void XXXtestExceptionInMethod() { - try { - new Runner().run(ExceptionInMethodBenchmark.class.getName()); - fail(); - } catch (ExceptionFromUserCodeException ignored) { - } - } - - static class ExceptionInMethodBenchmark extends SimpleBenchmark { - public void timeSomething(int reps) { - throw new SomeUserException(); - } - } -} diff --git a/src/test/RunXmlTest.java b/src/test/RunXmlTest.java deleted file mode 100644 index 6dd2b63..0000000 --- a/src/test/RunXmlTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010 Google 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 test; - -import com.google.caliper.Run; -import com.google.caliper.Scenario; -import com.google.caliper.Xml; -import com.google.common.collect.ImmutableMap; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.util.Date; -import junit.framework.TestCase; - -public class RunXmlTest extends TestCase { - - public void testXmlRoundtrip() { - Scenario a15dalvik = new Scenario(ImmutableMap.of( - "foo", "A", "bar", "15", "vm", "dalvikvm")); - Scenario b15dalvik = new Scenario(ImmutableMap.of( - "foo", "B", "bar", "15", "vm", "dalvikvm")); - - Run toEncode = new Run(ImmutableMap.of(a15dalvik, 1200.1, b15dalvik, 1100.2), - "examples.FooBenchmark", "A0:1F:CAFE:BABE", new Date()); - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - Xml.runToXml(toEncode, bytesOut); - - assertEquals("", new String(bytesOut.toByteArray())); - - // we don't validate the XML directly because it's a hassle to cope with arbitrary orderings of - // an element's attributes - - ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray()); - Run decoded = Xml.runFromXml(bytesIn); - - assertEquals(toEncode, decoded); - } -} diff --git a/src/test/SystemOutAndErrBenchmark.java b/src/test/SystemOutAndErrBenchmark.java deleted file mode 100644 index df37d76..0000000 --- a/src/test/SystemOutAndErrBenchmark.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010 Google 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 test; - -import com.google.caliper.SimpleBenchmark; -import com.google.caliper.Runner; - -/** - * Demonstrates that the benchmark can emit output without consequence. - */ -public class SystemOutAndErrBenchmark extends SimpleBenchmark { - - public void timeSystemOutAndSystemErr(int reps) { - for (int i = 0; i < reps; i++) { - System.out.println("hello, out"); - System.err.println("hello, err"); - } - } - - public static void main(String[] args) { - Runner.main(SystemOutAndErrBenchmark.class, args); - } -} diff --git a/src/test/ThreadSleepBenchmark.java b/src/test/ThreadSleepBenchmark.java deleted file mode 100644 index bfb6c05..0000000 --- a/src/test/ThreadSleepBenchmark.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2009 Google 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 test; - -import com.google.caliper.Runner; -import com.google.caliper.SimpleBenchmark; - -/** - * If everything is working properly, this should report runtime very close to - * 1ms. - */ -public class ThreadSleepBenchmark extends SimpleBenchmark { - - public void timeSleep(int reps) { - try { - Thread.sleep(reps); - } catch (InterruptedException ignored) { - } - } - - public static void main(String[] args) throws Exception { - Runner.main(ThreadSleepBenchmark.class, args); - } -} diff --git a/src/test/TracingBenchmark.java b/src/test/TracingBenchmark.java deleted file mode 100644 index 2f1c077..0000000 --- a/src/test/TracingBenchmark.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2010 Google 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 test; - -import com.google.caliper.Benchmark; -import com.google.caliper.TimedRunnable; -import com.google.caliper.Runner; -import java.util.Set; -import java.util.Map; - -/** - * Proof-of-concept of a decorating benchmark. - */ -public class TracingBenchmark implements Benchmark { - - private final Benchmark delegate; - - public TracingBenchmark() { - this.delegate = new ThreadSleepBenchmark(); - } - - public Set<String> parameterNames() { - return delegate.parameterNames(); - } - - public Set<String> parameterValues(String parameterName) { - return delegate.parameterValues(parameterName); - } - - public TimedRunnable createBenchmark(Map<String, String> parameterValues) { - final TimedRunnable benchmark = delegate.createBenchmark(parameterValues); - - return new TimedRunnable() { - public Object run(int reps) throws Exception { - // TODO: can we move the setup/tear down work out of the timed loop? - Runtime.getRuntime().traceMethodCalls(true); - try { - return benchmark.run(reps); - } finally { - Runtime.getRuntime().traceMethodCalls(false); - } - } - }; - } - - public static void main(String[] args) { - Runner.main(TracingBenchmark.class); - } -} diff --git a/src/tutorial/Tutorial.java b/src/tutorial/Tutorial.java deleted file mode 100644 index 06e6e56..0000000 --- a/src/tutorial/Tutorial.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2009 Google 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 tutorial; - -import com.google.caliper.Param; -import com.google.caliper.SimpleBenchmark; - -/** - * Caliper tutorial. To run the example benchmarks in this file: - * {@code CLASSPATH=... [caliper_home]/caliper tutorial.Tutorial.Benchmark1} - * - * @author Kevin Bourrillion - */ -public class Tutorial { - - /* - * We begin the Caliper tutorial with the simplest benchmark you can write. - * We'd like to know how efficient the method System.nanoTime() is. - * - * Notice: - * - * - We write a class that extends com.google.caliper.SimpleBenchmark. - * - It contains a public instance method whose name begins with 'time' and - * and which accepts a single 'int reps' parameter. - * - The body of the method simply executes the code we wish to measure, - * 'reps' times. - * - * Example run: - * - * $ CLASSPATH=build/classes/test caliper tutorial.Tutorial.Benchmark1 - * [real-time results appear on this line] - * - * Summary report for tutorial.Tutorial$Benchmark1: - * - * Benchmark ns - * --------- --- - * NanoTime 233 - */ - public static class Benchmark1 extends SimpleBenchmark { - public void timeNanoTime(int reps) { - for (int i = 0; i < reps; i++) { - System.nanoTime(); - } - } - } - - /* - * Now let's compare two things: nanoTime() versus currentTimeMillis(). - * Notice: - * - * - We simply add another method, following the same rules as the first. - * - * Example run output: - * - * Benchmark ns - * ----------------- --- - * NanoTime 248 - * CurrentTimeMillis 118 - */ - public static class Benchmark2 extends SimpleBenchmark { - public void timeNanoTime(int reps) { - for (int i = 0; i < reps; i++) { - System.nanoTime(); - } - } - public void timeCurrentTimeMillis(int reps) { - for (int i = 0; i < reps; i++) { - System.currentTimeMillis(); - } - } - } - - /* - * Let's try iterating over a large array. This seems simple enough, but - * there is a problem! - */ - public static class Benchmark3 extends SimpleBenchmark { - private final int[] array = new int[1000000]; - - @SuppressWarnings("UnusedDeclaration") // IDEA tries to warn us! - public void timeArrayIteration_BAD(int reps) { - for (int i = 0; i < reps; i++) { - for (int ignoreMe : array) {} - } - } - } - - /* - * Caliper reported that the benchmark above ran in 4 nanoseconds. - * - * Wait, what? - * - * How can it possibly iterate over a million zeroes in 4 ns!? - * - * It is very important to sanity-check benchmark results with common sense! - * In this case, we're indeed getting a bogus result. The problem is that the - * Java Virtual Machine is too smart: it detected the fact that the loop was - * producing no actual result, so it simply compiled it right out. The method - * never looped at all. To fix this, we need to use a dummy result value. - * - * Notice: - * - * - We simply change the 'time' method from 'void' to any return type we - * wish. Then we return a value that can't be known without actually - * performing the work, and thus we defeat the runtime optimizations. - * - We're no longer timing *just* the code we want to be testing - our - * result will now be inflated by the (small) cost of addition. This is an - * unfortunate fact of life with microbenchmarking. In fact, we were - * already inflated by the cost of an int comparison, "i < reps" as it was. - * - * With this change, Caliper should report a much more realistic value, more - * on the order of an entire millisecond. - */ - public static class Benchmark4 extends SimpleBenchmark { - private final int[] array = new int[1000000]; - - public int timeArrayIteration_fixed(int reps) { - int dummy = 0; - for (int i = 0; i < reps; i++) { - for (int doNotIgnoreMe : array) { - dummy += doNotIgnoreMe; - } - } - return dummy; // framework ignores this, but it has served its purpose! - } - } - - /* - * Now we'd like to know how various other *sizes* of arrays perform. We - * don't want to have to cut and paste the whole benchmark just to provide a - * different size. What we need is a parameter! - * - * When you run this benchmark the same way you ran the previous ones, you'll - * now get an error: "No values provided for benchmark parameter 'size'". - * You can provide the value requested at the command line like this: - * - * [caliper_home]/caliper tutorial.Tutorial.Benchmark5 -Dsize=100} - * - * You'll see output like this: - * - * Benchmark size ns - * -------------- ---- --- - * ArrayIteration 100 51 - * - * Now that we've parameterized our benchmark, things are starting to get fun. - * Try passing '-Dsize=10,100,1000' and see what happens! - * - * Benchmark size ns - * -------------- ---- ----------------------------------- - * ArrayIteration 10 7 | - * ArrayIteration 100 49 |||| - * ArrayIteration 1000 477 |||||||||||||||||||||||||||||| - * - */ - public static class Benchmark5 extends SimpleBenchmark { - @Param int size; // set automatically by framework - - private int[] array; // set by us, in setUp() - - @Override protected void setUp() { - // @Param values are guaranteed to have been injected by now - array = new int[size]; - } - - public int timeArrayIteration(int reps) { - int dummy = 0; - for (int i = 0; i < reps; i++) { - for (int doNotIgnoreMe : array) { - dummy += doNotIgnoreMe; - } - } - return dummy; - } - } -} |