aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2009-12-15 18:54:02 -0800
committerJesse Wilson <jessewilson@google.com>2009-12-15 18:54:02 -0800
commit1440b36663f61ebde1952d91b4a1f4c1a27fcefa (patch)
tree35e2458d47b0de58bad416e002dc9f1e039ba9fd
parentda6e661c7e42d1358c2a49f0f02c7adc8e0a1671 (diff)
downloadcaliper-1440b36663f61ebde1952d91b4a1f4c1a27fcefa.tar.gz
Updating caliper to current SVN as of 20091215
A test A test/com A test/com/google A test/com/google/caliper A test/com/google/caliper/AllTests.java A test/com/google/caliper/examples A test/com/google/caliper/examples/ArraySortBenchmark.java A test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java A test/com/google/caliper/examples/ListIterationBenchmark.java A test/com/google/caliper/examples/IntModBenchmark.java A test/com/google/caliper/examples/CharacterBenchmark.java A test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java A test/com/google/caliper/examples/StringBuilderBenchmark.java A test/com/google/caliper/examples/EnumSetContainsBenchmark.java A test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java A test/com/google/caliper/examples/FormatterBenchmark.java A lib A lib/junit.jar A lib/google-collect-1.0-rc4.jar A src A src/com A src/com/google A src/com/google/caliper A src/com/google/caliper/Caliper.java A src/com/google/caliper/Param.java A src/com/google/caliper/Parameter.java A src/com/google/caliper/ExecutionException.java A src/com/google/caliper/Run.java A src/com/google/caliper/SimpleBenchmark.java A src/com/google/caliper/ConfigurationException.java A src/com/google/caliper/Runner.java A src/com/google/caliper/TypeConverter.java A src/com/google/caliper/TimedRunnable.java A src/com/google/caliper/Benchmark.java A src/com/google/caliper/ConsoleReport.java A src/com/google/caliper/Result.java A caliper.ipr A core.iml A COPYING A build.xml Checked out revision 23.
-rw-r--r--src/com/google/caliper/Benchmark.java26
-rw-r--r--src/com/google/caliper/Caliper.java9
-rw-r--r--src/com/google/caliper/ConsoleReport.java28
-rw-r--r--src/com/google/caliper/DefaultBenchmarkSuite.java180
-rw-r--r--src/com/google/caliper/Param.java2
-rw-r--r--src/com/google/caliper/Parameter.java8
-rw-r--r--src/com/google/caliper/Run.java13
-rw-r--r--src/com/google/caliper/Runner.java102
-rw-r--r--src/com/google/caliper/SimpleBenchmark.java171
-rw-r--r--src/com/google/caliper/TimedRunnable.java (renamed from src/com/google/caliper/BenchmarkSuite.java)28
-rw-r--r--test/com/google/caliper/AllTests.java2
-rw-r--r--test/com/google/caliper/DefaultBenchmarkSuiteTest.java91
-rw-r--r--test/com/google/caliper/examples/ArraySortBenchmark.java (renamed from test/com/google/caliper/examples/SortBenchmarkSuite.java)29
-rw-r--r--test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java80
-rw-r--r--test/com/google/caliper/examples/CharacterBenchmark.java173
-rw-r--r--test/com/google/caliper/examples/DoubleToStringBenchmarkSuite.java77
-rw-r--r--test/com/google/caliper/examples/EnumSetContainsBenchmark.java (renamed from test/com/google/caliper/examples/EnumSetContainsBenchmarkSuite.java)25
-rw-r--r--test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java71
-rw-r--r--test/com/google/caliper/examples/FormatterBenchmark.java77
-rw-r--r--test/com/google/caliper/examples/FormatterBenchmarkSuite.java98
-rw-r--r--test/com/google/caliper/examples/IntModBenchmark.java90
-rw-r--r--test/com/google/caliper/examples/ListIterationBenchmark.java (renamed from test/com/google/caliper/examples/ListIterationBenchmarkSuite.java)48
-rw-r--r--test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java80
-rw-r--r--test/com/google/caliper/examples/StringBuilderBenchmark.java132
24 files changed, 1009 insertions, 631 deletions
diff --git a/src/com/google/caliper/Benchmark.java b/src/com/google/caliper/Benchmark.java
index bd60b45..19426e6 100644
--- a/src/com/google/caliper/Benchmark.java
+++ b/src/com/google/caliper/Benchmark.java
@@ -16,18 +16,18 @@
package com.google.caliper;
-public abstract class Benchmark {
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Set;
- /**
- * 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.
- */
- public abstract Object run(int trials) throws Exception;
+/**
+ * A collection of benchmarks that share a set of configuration parameters.
+ */
+public interface Benchmark {
+
+ Set<String> parameterNames();
+
+ Set<String> parameterValues(String parameterName);
- @Override public String toString() {
- return getClass().getSimpleName();
- }
-}
+ 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
index 855101e..315431f 100644
--- a/src/com/google/caliper/Caliper.java
+++ b/src/com/google/caliper/Caliper.java
@@ -34,13 +34,13 @@ class Caliper {
this.runNanos = runMillis * 1000000;
}
- public double warmUp(Benchmark benchmark) throws Exception {
+ public double warmUp(TimedRunnable timedRunnable) throws Exception {
long startNanos = System.nanoTime();
long endNanos = startNanos + warmupNanos;
int trials = 0;
long currentNanos;
while ((currentNanos = System.nanoTime()) < endNanos) {
- benchmark.run(1);
+ timedRunnable.run(1);
trials++;
}
double nanosPerExecution = (currentNanos - startNanos) / trials;
@@ -54,8 +54,11 @@ class Caliper {
* 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(Benchmark test, double estimatedNanosPerTrial) throws Exception {
+ public double run(TimedRunnable test, double estimatedNanosPerTrial) throws Exception {
int trials = (int) (runNanos / estimatedNanosPerTrial);
+ if (trials == 0) {
+ trials = 1;
+ }
long startNanos = System.nanoTime();
test.run(trials);
long endNanos = System.nanoTime();
diff --git a/src/com/google/caliper/ConsoleReport.java b/src/com/google/caliper/ConsoleReport.java
index 790ffe0..b367ec4 100644
--- a/src/com/google/caliper/ConsoleReport.java
+++ b/src/com/google/caliper/ConsoleReport.java
@@ -18,7 +18,10 @@ package com.google.caliper;
import com.google.common.collect.*;
-import java.util.*;
+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
@@ -36,13 +39,14 @@ import java.util.*;
final class ConsoleReport {
private static final int bargraphWidth = 30;
- private static final String benchmarkKey = "benchmark";
private static final String vmKey = "vm";
private final List<Parameter> parameters;
private final Result result;
private final List<Run> runs;
+ private final double minValue;
+ private final double maxValue;
private final double logMaxValue;
private final int decimalDigits;
private final double divideBy;
@@ -61,15 +65,14 @@ final class ConsoleReport {
Run run = entry.getKey();
double d = entry.getValue();
- minValue = minValue < d ? minValue : d;
- maxValue = maxValue > d ? maxValue : d;
+ minValue = Math.min(minValue, d);
+ maxValue = Math.max(maxValue, d);
for (Map.Entry<String, String> parameter : run.getParameters().entrySet()) {
String name = parameter.getKey();
nameToValues.put(name, parameter.getValue());
}
- nameToValues.put(benchmarkKey, run.getBenchmarkClass().getSimpleName());
nameToValues.put(vmKey, run.getVm());
}
@@ -109,6 +112,8 @@ final class ConsoleReport {
this.parameters = new StandardDeviationOrdering().reverse().sortedCopy(parametersBuilder);
this.runs = new ByParametersOrdering().sortedCopy(result.getMeasurements().keySet());
+ this.minValue = minValue;
+ this.maxValue = maxValue;
this.logMaxValue = Math.log(maxValue);
int numDigitsInMin = (int) Math.ceil(Math.log10(minValue));
@@ -155,9 +160,7 @@ final class ConsoleReport {
}
String get(Run run) {
- if (benchmarkKey.equals(name)) {
- return run.getBenchmarkClass().getSimpleName();
- } else if (vmKey.equals(name)) {
+ if (vmKey.equals(name)) {
return run.getVm();
} else {
return run.getParameters().get(name);
@@ -210,6 +213,7 @@ final class ConsoleReport {
* Prints a table of values.
*/
private void printValues() {
+ // header
for (Parameter parameter : parameters) {
if (parameter.isInteresting()) {
System.out.printf("%" + parameter.maxLength + "s ", parameter.name);
@@ -217,6 +221,7 @@ final class ConsoleReport {
}
System.out.printf("%" + measurementColumnLength + "s logarithmic runtime%n", units);
+ // rows
String numbersFormat = "%" + measurementColumnLength + "." + decimalDigits + "f %s%n";
for (Run run : runs) {
for (Parameter parameter : parameters) {
@@ -245,10 +250,15 @@ final class ConsoleReport {
* value.
*/
private String bargraph(double value) {
+ int numLinearChars = (int) ((value / maxValue) * bargraphWidth);
double logValue = Math.log(value);
int numChars = (int) ((logValue / logMaxValue) * bargraphWidth);
StringBuilder result = new StringBuilder(numChars);
- for (int i = 0; i < numChars; i++) {
+ for (int i = 0; i < numLinearChars; i++) {
+ result.append("X");
+ }
+
+ for (int i = numLinearChars; i < numChars; i++) {
result.append("|");
}
return result.toString();
diff --git a/src/com/google/caliper/DefaultBenchmarkSuite.java b/src/com/google/caliper/DefaultBenchmarkSuite.java
deleted file mode 100644
index 0e197f6..0000000
--- a/src/com/google/caliper/DefaultBenchmarkSuite.java
+++ /dev/null
@@ -1,180 +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.Constructor;
-import java.lang.reflect.Type;
-import java.util.*;
-
-/**
- * A convenience class for implementing benchmark suites in plain code.
- * Implementing classes must have a no-arguments constructor.
- *
- * <h3>Benchmarks</h3>
- * The benchmarks of a suite are defined by inner classes within the suite.
- * These inner classes implement the {@link Benchmark} interface. They may be
- * static. They are not permitted to take parameters in their constructors.
- *
- * <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&lt;Integer&gt; 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&lt;Integer&gt; lengthValues() {
- * return Arrays.asList(10, 100, 1000, 10000);
- * }
- * </pre>
- */
-public abstract class DefaultBenchmarkSuite extends BenchmarkSuite {
-
- private final Map<String, Parameter<?>> parameters;
- private final Map<Class<? extends Benchmark>, BenchmarkFactory> benchmarkFactories;
-
- protected void setUp() throws Exception {}
-
- protected DefaultBenchmarkSuite() {
- parameters = Parameter.forClass(getClass());
- benchmarkFactories = createBenchmarkFactories();
-
- if (benchmarkFactories.isEmpty()) {
- throw new ConfigurationException(
- "No benchmarks defined in " + getClass().getName());
- }
- }
-
- protected Set<Class<? extends Benchmark>> benchmarkClasses() {
- return benchmarkFactories.keySet();
- }
-
- protected Set<String> parameterNames() {
- return parameters.keySet();
- }
-
- protected Set<String> parameterValues(String parameterName) {
- try {
- TypeConverter typeConverter = new TypeConverter();
- Parameter<?> parameter = parameters.get(parameterName);
- if (parameter == null) {
- throw new IllegalArgumentException();
- }
- Collection<?> values = parameter.values();
- Type type = parameter.getType();
- Set<String> result = new LinkedHashSet<String>();
- for (Object value : values) {
- result.add(typeConverter.toString(value, type));
- }
- return result;
- } catch (Exception e) {
- throw new ExecutionException(e);
- }
- }
-
- protected Benchmark createBenchmark(Class<? extends Benchmark> benchmarkClass,
- Map<String, String> parameterValues) {
- TypeConverter typeConverter = new TypeConverter();
-
- BenchmarkFactory benchmarkFactory = benchmarkFactories.get(benchmarkClass);
- if (benchmarkFactory == null) {
- throw new IllegalArgumentException();
- }
-
- if (!parameters.keySet().equals(parameterValues.keySet())) {
- throw new IllegalArgumentException("Invalid parameters specified. Expected "
- + parameters.keySet() + " but was " + parameterValues.keySet());
- }
-
- try {
- DefaultBenchmarkSuite copyOfSelf = getClass().newInstance();
- Benchmark benchmark = benchmarkFactory.create(copyOfSelf);
- for (Map.Entry<String, String> entry : parameterValues.entrySet()) {
- Parameter parameter = parameters.get(entry.getKey());
- Object value = typeConverter.fromString(entry.getValue(), parameter.getType());
- parameter.set(copyOfSelf, value);
- }
-
- copyOfSelf.setUp();
- return benchmark;
-
- } catch (Exception e) {
- throw new ExecutionException(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<Class<? extends Benchmark>, BenchmarkFactory> createBenchmarkFactories() {
- Map<Class<? extends Benchmark>, BenchmarkFactory> result
- = new LinkedHashMap<Class<? extends Benchmark>, BenchmarkFactory>();
- for (Class<?> c : getClass().getDeclaredClasses()) {
- if (!Benchmark.class.isAssignableFrom(c) || c.isInterface()) {
- continue;
- }
-
- @SuppressWarnings("unchecked") // guarded by isAssignableFrom
- Class<? extends Benchmark> benchmarkClass = (Class<? extends Benchmark>) c;
-
- try {
- final Constructor<? extends Benchmark> constructor
- = benchmarkClass.getDeclaredConstructor();
- constructor.setAccessible(true);
- result.put(benchmarkClass, new BenchmarkFactory() {
- public Benchmark create(BenchmarkSuite suite) throws Exception {
- return constructor.newInstance();
- }
- });
- continue;
- } catch (NoSuchMethodException ignored) {
- }
-
- try {
- final Constructor<? extends Benchmark> constructor
- = benchmarkClass.getDeclaredConstructor(getClass());
- constructor.setAccessible(true);
- result.put(benchmarkClass, new BenchmarkFactory() {
- public Benchmark create(BenchmarkSuite suite) throws Exception {
- return constructor.newInstance(suite);
- }
- });
- continue;
- } catch (NoSuchMethodException ignored) {
- }
-
- throw new ConfigurationException("No usable constructor for "
- + benchmarkClass.getName() + "\n Benchmarks may only use no arguments constructors.");
- }
-
- return result;
- }
-
- interface BenchmarkFactory {
- Benchmark create(BenchmarkSuite suite) throws Exception;
- }
-} \ No newline at end of file
diff --git a/src/com/google/caliper/Param.java b/src/com/google/caliper/Param.java
index 0a9b203..28d3588 100644
--- a/src/com/google/caliper/Param.java
+++ b/src/com/google/caliper/Param.java
@@ -22,7 +22,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Annotates the field accepting a parameter in a {@link DefaultBenchmarkSuite}.
+ * Annotates the field accepting a parameter in a {@link SimpleBenchmark}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
diff --git a/src/com/google/caliper/Parameter.java b/src/com/google/caliper/Parameter.java
index a5ab6c8..1ba77b5 100644
--- a/src/com/google/caliper/Parameter.java
+++ b/src/com/google/caliper/Parameter.java
@@ -20,7 +20,7 @@ import java.lang.reflect.*;
import java.util.*;
/**
- * A parameter in a {@link DefaultBenchmarkSuite}.
+ * A parameter in a {@link SimpleBenchmark}.
*/
abstract class Parameter<T> {
@@ -33,7 +33,7 @@ abstract class Parameter<T> {
/**
* Returns all properties for the given class.
*/
- public static Map<String, Parameter<?>> forClass(Class<? extends BenchmarkSuite> suiteClass) {
+ public static Map<String, Parameter<?>> forClass(Class<? extends Benchmark> suiteClass) {
Map<String, Parameter<?>> parameters = new TreeMap<String, Parameter<?>>();
for (final Field field : suiteClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Param.class)) {
@@ -46,7 +46,7 @@ abstract class Parameter<T> {
}
public static Parameter forField(
- Class<? extends BenchmarkSuite> suiteClass, final Field field) {
+ Class<? extends Benchmark> suiteClass, final Field field) {
Parameter result = null;
Type returnType = null;
Member member = null;
@@ -110,7 +110,7 @@ abstract class Parameter<T> {
/**
* Sets the value of this property to the specified value for the given suite.
*/
- public void set(BenchmarkSuite suite, Object value) throws Exception {
+ public void set(Benchmark suite, Object value) throws Exception {
field.set(suite, value);
}
diff --git a/src/com/google/caliper/Run.java b/src/com/google/caliper/Run.java
index 5ab8856..a9109de 100644
--- a/src/com/google/caliper/Run.java
+++ b/src/com/google/caliper/Run.java
@@ -18,6 +18,7 @@ package com.google.caliper;
import com.google.common.collect.ImmutableMap;
+import java.lang.reflect.Method;
import java.util.Map;
/**
@@ -26,13 +27,9 @@ import java.util.Map;
final class Run {
private final ImmutableMap<String, String> parameters;
- private final Class<? extends Benchmark> benchmarkClass;
private final String vm;
- public Run(Map<String, String> parameters,
- Class<? extends Benchmark> benchmarkClass,
- String vm) {
- this.benchmarkClass = benchmarkClass;
+ public Run(Map<String, String> parameters, String vm) {
this.parameters = ImmutableMap.copyOf(parameters);
this.vm = vm;
}
@@ -41,15 +38,11 @@ final class Run {
return parameters;
}
- public Class<? extends Benchmark> getBenchmarkClass() {
- return benchmarkClass;
- }
-
public String getVm() {
return vm;
}
@Override public String toString() {
- return benchmarkClass.getSimpleName() + " " + parameters;
+ return "Run" + parameters;
}
}
diff --git a/src/com/google/caliper/Runner.java b/src/com/google/caliper/Runner.java
index 68f26f1..72442db 100644
--- a/src/com/google/caliper/Runner.java
+++ b/src/com/google/caliper/Runner.java
@@ -16,10 +16,10 @@
package com.google.caliper;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Multimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
import java.io.BufferedReader;
import java.io.File;
@@ -35,7 +35,7 @@ import java.util.*;
public final class Runner {
private String suiteClassName;
- private BenchmarkSuite suite;
+ private Benchmark suite;
/** Effective parameters to run in the benchmark. */
private Multimap<String, String> parameters = LinkedHashMultimap.create();
@@ -50,12 +50,6 @@ public final class Runner {
private Multimap<String, String> userParameters = LinkedHashMultimap.create();
/**
- * Benchmark class specified by the user on the command line; or null to run
- * the complete set of benchmark classes.
- */
- private Class<? extends Benchmark> userBenchmarkClass;
-
- /**
* True if each benchmark should run in process.
*/
private boolean inProcess;
@@ -75,13 +69,13 @@ public final class Runner {
private void prepareSuite() {
try {
@SuppressWarnings("unchecked") // guarded by the if statement that follows
- Class<? extends BenchmarkSuite> suiteClass
- = (Class<? extends BenchmarkSuite>) Class.forName(suiteClassName);
- if (!BenchmarkSuite.class.isAssignableFrom(suiteClass)) {
+ Class<? extends Benchmark> suiteClass
+ = (Class<? extends Benchmark>) Class.forName(suiteClassName);
+ if (!Benchmark.class.isAssignableFrom(suiteClass)) {
throw new ConfigurationException(suiteClass + " is not a benchmark suite.");
}
- Constructor<? extends BenchmarkSuite> constructor = suiteClass.getDeclaredConstructor();
+ Constructor<? extends Benchmark> constructor = suiteClass.getDeclaredConstructor();
suite = constructor.newInstance();
} catch (InvocationTargetException e) {
throw new ExecutionException(e.getCause());
@@ -121,33 +115,14 @@ public final class Runner {
private List<Run> createRuns() throws Exception {
List<RunBuilder> builders = new ArrayList<RunBuilder>();
- // create runs for each benchmark class
- Set<Class<? extends Benchmark>> benchmarkClasses = (userBenchmarkClass != null)
- ? ImmutableSet.<Class<? extends Benchmark>>of(userBenchmarkClass)
- : suite.benchmarkClasses();
- for (Class<? extends Benchmark> benchmarkClass : benchmarkClasses) {
- RunBuilder builder = new RunBuilder();
- builder.benchmarkClass = benchmarkClass;
- builders.add(builder);
- }
-
- // multiply the runs by the number of VMs
+ // create runs for each VMs
Set<String> vms = userVms.isEmpty()
? defaultVms()
: userVms;
- Iterator<String> vmIterator = vms.iterator();
- String firstVm = vmIterator.next();
- for (RunBuilder builder : builders) {
- builder.vm = firstVm;
- }
- int length = builders.size();
- while (vmIterator.hasNext()) {
- String alternateVm = vmIterator.next();
- for (int s = 0; s < length; s++) {
- RunBuilder copy = builders.get(s).copy();
- copy.vm = alternateVm;
- builders.add(copy);
- }
+ for (String vm : vms) {
+ RunBuilder runBuilder = new RunBuilder();
+ runBuilder.vm = vm;
+ builders.add(runBuilder);
}
for (Map.Entry<String, Collection<String>> parameter : parameters.asMap().entrySet()) {
@@ -164,10 +139,10 @@ public final class Runner {
}
// multiply the size of the specs by the number of alternate values
- length = builders.size();
+ int size = builders.size();
while (values.hasNext()) {
String alternate = values.next();
- for (int s = 0; s < length; s++) {
+ for (int s = 0; s < size; s++) {
RunBuilder copy = builders.get(s).copy();
copy.parameters.put(key, alternate);
builders.add(copy);
@@ -185,19 +160,17 @@ public final class Runner {
static class RunBuilder {
Map<String, String> parameters = new LinkedHashMap<String, String>();
- Class<? extends Benchmark> benchmarkClass;
String vm;
RunBuilder copy() {
RunBuilder result = new RunBuilder();
result.parameters.putAll(parameters);
- result.benchmarkClass = benchmarkClass;
result.vm = vm;
return result;
}
public Run build() {
- return new Run(parameters, benchmarkClass, vm);
+ return new Run(parameters, vm);
}
}
@@ -213,8 +186,6 @@ public final class Runner {
command.add("--runMillis");
command.add(String.valueOf(runMillis));
command.add("--inProcess");
- command.add("--benchmark");
- command.add(run.getBenchmarkClass().getName());
for (Map.Entry<String, String> entry : run.getParameters().entrySet()) {
command.add("-D" + entry.getKey() + "=" + entry.getValue());
}
@@ -270,6 +241,14 @@ public final class Runner {
afterRun(nanosPerTrial);
resultsBuilder.put(run, nanosPerTrial);
}
+
+ // blat out our progress bar
+ System.out.print("\r");
+ for (int j = 0; j < 80; j++) {
+ System.out.print(" ");
+ }
+ System.out.print("\r");
+
return new Result(resultsBuilder.build());
} catch (Exception e) {
throw new ExecutionException(e);
@@ -283,12 +262,12 @@ public final class Runner {
if (runString.length() > runStringLength) {
runString = runString.substring(0, runStringLength);
}
- System.out.printf("%2.0f%% %-" + runStringLength + "s",
+ System.out.printf("\r%2.0f%% %-" + runStringLength + "s",
percentDone * 100, runString);
}
private void afterRun(double nanosPerTrial) {
- System.out.printf(" %10.0fns%n", nanosPerTrial);
+ System.out.printf(" %10.0fns", nanosPerTrial);
}
private void runInProcess() {
@@ -297,10 +276,9 @@ public final class Runner {
for (Run run : createRuns()) {
double result;
- Benchmark benchmark = suite.createBenchmark(
- run.getBenchmarkClass(), run.getParameters());
- double warmupNanosPerTrial = caliper.warmUp(benchmark);
- result = caliper.run(benchmark, warmupNanosPerTrial);
+ TimedRunnable timedRunnable = suite.createBenchmark(run.getParameters());
+ double warmupNanosPerTrial = caliper.warmUp(timedRunnable);
+ result = caliper.run(timedRunnable, warmupNanosPerTrial);
double nanosPerTrial = result;
System.out.println(nanosPerTrial);
}
@@ -309,24 +287,11 @@ public final class Runner {
}
}
- private boolean parseArgs(String[] args) {
+ private boolean parseArgs(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
if ("--help".equals(args[i])) {
return false;
- } else if ("--benchmark".equals(args[i])) {
- try {
- @SuppressWarnings("unchecked") // guarded immediately afterwards!
- Class<? extends Benchmark> c = (Class<? extends Benchmark>) Class.forName(args[++i]);
- if (!Benchmark.class.isAssignableFrom(c)) {
- System.out.println("Not a benchmark class: " + c);
- return false;
- }
- userBenchmarkClass = c;
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
-
} else if ("--inProcess".equals(args[i])) {
inProcess = true;
@@ -358,9 +323,7 @@ public final class Runner {
System.out.println("Too many benchmark classes!");
return false;
}
-
suiteClassName = args[i];
-
}
}
@@ -388,8 +351,6 @@ public final class Runner {
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(" --benchmark <class>: fix a benchmark executable to the named class");
- 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");
@@ -403,7 +364,7 @@ public final class Runner {
// adding new options? don't forget to update executeForked()
}
- public static void main(String... args) {
+ public static void main(String... args) throws Exception { // TODO: cleaner error reporting
Runner runner = new Runner();
if (!runner.parseArgs(args)) {
runner.printUsage();
@@ -418,11 +379,10 @@ public final class Runner {
}
Result result = runner.runOutOfProcess();
- System.out.println();
new ConsoleReport(result).displayResults();
}
- public static void main(Class<? extends BenchmarkSuite> suite, String... args) {
+ public static void main(Class<? extends Benchmark> suite, String... args) throws Exception {
String[] argsWithSuiteName = new String[args.length + 1];
System.arraycopy(args, 0, argsWithSuiteName, 0, args.length);
argsWithSuiteName[args.length] = suite.getName();
diff --git a/src/com/google/caliper/SimpleBenchmark.java b/src/com/google/caliper/SimpleBenchmark.java
new file mode 100644
index 0000000..8d2d4b1
--- /dev/null
+++ b/src/com/google/caliper/SimpleBenchmark.java
@@ -0,0 +1,171 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+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&lt;Integer&gt; 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&lt;Integer&gt; 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();
+ }
+
+ try {
+ TypeConverter typeConverter = new TypeConverter();
+ Parameter<?> parameter = parameters.get(parameterName);
+ if (parameter == null) {
+ throw new IllegalArgumentException();
+ }
+ Collection<?> values = parameter.values();
+ Type type = parameter.getType();
+
+ ImmutableSet.Builder<String> result = ImmutableSet.builder();
+ for (Object value : values) {
+ result.add(typeConverter.toString(value, type));
+ }
+ return result.build();
+ } catch (Exception e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+ public TimedRunnable createBenchmark(Map<String, String> parameterValues) {
+ TypeConverter typeConverter = new TypeConverter();
+
+ if (!parameterNames().equals(parameterValues.keySet())) {
+ throw new IllegalArgumentException("Invalid parameters specified. Expected "
+ + parameterNames() + " but was " + parameterValues.keySet());
+ }
+
+ try {
+ 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 ExecutionException(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 (final 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/BenchmarkSuite.java b/src/com/google/caliper/TimedRunnable.java
index 40106a0..d1f9a6c 100644
--- a/src/com/google/caliper/BenchmarkSuite.java
+++ b/src/com/google/caliper/TimedRunnable.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,20 +16,14 @@
package com.google.caliper;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A collection of benchmarks that share a set of configuration parameters.
- */
-public abstract class BenchmarkSuite {
-
- protected abstract Set<Class<? extends Benchmark>> benchmarkClasses();
-
- protected abstract Set<String> parameterNames();
-
- protected abstract Set<String> parameterValues(String parameterName);
+public interface TimedRunnable {
- protected abstract Benchmark createBenchmark(
- Class<? extends Benchmark> benchmark, Map<String, String> parameterValues);
-} \ No newline at end of file
+ /**
+ * 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/test/com/google/caliper/AllTests.java b/test/com/google/caliper/AllTests.java
index 55f620a..510cc0a 100644
--- a/test/com/google/caliper/AllTests.java
+++ b/test/com/google/caliper/AllTests.java
@@ -22,7 +22,7 @@ import junit.framework.TestSuite;
public final class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite();
- suite.addTestSuite(DefaultBenchmarkSuiteTest.class);
+ // tests go here :)
return suite;
}
}
diff --git a/test/com/google/caliper/DefaultBenchmarkSuiteTest.java b/test/com/google/caliper/DefaultBenchmarkSuiteTest.java
deleted file mode 100644
index 232cb4c..0000000
--- a/test/com/google/caliper/DefaultBenchmarkSuiteTest.java
+++ /dev/null
@@ -1,91 +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 com.google.common.collect.ImmutableSet;
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-public class DefaultBenchmarkSuiteTest extends TestCase {
-
- public void testIntrospection() {
- SampleBenchmarkSuite suite = new SampleBenchmarkSuite();
- assertEquals(ImmutableSet.of("a", "b"), suite.parameterNames());
- assertEquals(ImmutableSet.of("1", "2", "3"), suite.parameterValues("a"));
- assertEquals(ImmutableSet.of("4"), suite.parameterValues("b"));
- assertEquals(ImmutableSet.of(
- SampleBenchmarkSuite.MultiplyBenchmark.class,
- SampleBenchmarkSuite.DivideBenchmark.class),
- suite.benchmarkClasses());
-
- }
-
- public void testCreateBenchmark() {
- SampleBenchmarkSuite originalSuite = new SampleBenchmarkSuite();
- Benchmark benchmark = originalSuite.createBenchmark(
- SampleBenchmarkSuite.MultiplyBenchmark.class,
- ImmutableMap.of("a", "2", "b", "4"));
-
- SampleBenchmarkSuite.MultiplyBenchmark multiplyBenchmark
- = (SampleBenchmarkSuite.MultiplyBenchmark) benchmark;
-
- SampleBenchmarkSuite multiplySuite = multiplyBenchmark.suite();
- assertNotSame(originalSuite, multiplySuite);
- assertEquals(2, multiplySuite.a);
- assertEquals(4, multiplySuite.b);
- }
-
- static class SampleBenchmarkSuite extends DefaultBenchmarkSuite {
- @Param int a;
-
- private static Collection<Integer> aValues = Arrays.asList(1, 2, 3);
-
- @Param int b;
-
- private static Collection<Integer> bValues() {
- return Arrays.asList(4);
- }
-
- class MultiplyBenchmark extends Benchmark {
- @Override public Object run(int trials) throws Exception {
- int result = 0;
- for (int i = 0; i < trials; i++) {
- result ^= a * b;
- }
- return result;
- }
-
- SampleBenchmarkSuite suite() {
- return SampleBenchmarkSuite.this;
- }
- }
-
- class DivideBenchmark extends Benchmark {
- @Override public Object run(int trials) throws Exception {
- int result = 0;
- for (int i = 0; i < trials; i++) {
- result ^= a / b;
- }
- return result;
- }
- }
- }
-}
diff --git a/test/com/google/caliper/examples/SortBenchmarkSuite.java b/test/com/google/caliper/examples/ArraySortBenchmark.java
index e92fc10..2978fa2 100644
--- a/test/com/google/caliper/examples/SortBenchmarkSuite.java
+++ b/test/com/google/caliper/examples/ArraySortBenchmark.java
@@ -16,20 +16,19 @@
package com.google.caliper.examples;
-import com.google.caliper.Benchmark;
-import com.google.caliper.DefaultBenchmarkSuite;
import com.google.caliper.Param;
import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
import java.util.Arrays;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.Random;
-import java.util.Collection;
/**
* Measures sorting on different distributions of integers.
*/
-public class SortBenchmarkSuite extends DefaultBenchmarkSuite {
+public class ArraySortBenchmark extends SimpleBenchmark {
@Param int length;
@@ -37,7 +36,7 @@ public class SortBenchmarkSuite extends DefaultBenchmarkSuite {
@Param Distribution distribution;
- static Collection<Distribution> distributionValues = EnumSet.allOf(Distribution.class);
+ static final Collection<Distribution> distributionValues = EnumSet.allOf(Distribution.class);
int[] values;
int[] copy;
@@ -47,16 +46,14 @@ public class SortBenchmarkSuite extends DefaultBenchmarkSuite {
copy = new int[length];
}
- class ArraysSortBenchmark extends Benchmark {
- public Object run(int trials) throws Exception {
- int result = 0;
- for (int i = 0; i < trials; i++) {
- System.arraycopy(values, 0, copy, 0, values.length);
- Arrays.sort(copy);
- result ^= copy[0];
- }
- return result;
+ public int timeSort(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ System.arraycopy(values, 0, copy, 0, values.length);
+ Arrays.sort(copy);
+ dummy ^= copy[0];
}
+ return dummy;
}
enum Distribution {
@@ -109,7 +106,7 @@ public class SortBenchmarkSuite extends DefaultBenchmarkSuite {
abstract int[] create(int length);
}
- public static void main(String[] args) {
- Runner.main(SortBenchmarkSuite.class, args);
+ public static void main(String[] args) throws Exception {
+ Runner.main(ArraySortBenchmark.class, args);
}
}
diff --git a/test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java b/test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java
new file mode 100644
index 0000000..5e6cbfa
--- /dev/null
+++ b/test/com/google/caliper/examples/BoxedDoubleToStringBenchmark.java
@@ -0,0 +1,80 @@
+/*
+ * 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.examples;
+
+import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Measures the various ways the JDK converts boxed Doubles to Strings.
+ */
+public class BoxedDoubleToStringBenchmark extends SimpleBenchmark {
+
+ @Param private Double d;
+
+ private static final Collection<Double> dValues = Arrays.asList(
+ 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/test/com/google/caliper/examples/CharacterBenchmark.java b/test/com/google/caliper/examples/CharacterBenchmark.java
new file mode 100644
index 0000000..3ffeb01
--- /dev/null
+++ b/test/com/google/caliper/examples/CharacterBenchmark.java
@@ -0,0 +1,173 @@
+/*
+ * 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.examples;
+
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.util.Collection;
+import java.util.EnumSet;
+
+/**
+ * Tests various Character methods, intended for testing multiple
+ * implementations against each other.
+ */
+public class CharacterBenchmark extends SimpleBenchmark {
+
+ @Param CharacterSet characterSet;
+ static Collection<CharacterSet> characterSetValues = EnumSet.allOf(CharacterSet.class);
+
+ char[] values;
+
+ @Override protected void setUp() throws Exception {
+ values = characterSet.chars;
+ }
+
+ enum CharacterSet {
+ ASCII(128),
+ UNICODE(65536);
+ char[] chars;
+ CharacterSet(int size) {
+ chars = new char[size];
+ for (int i = 0; i < chars.length; ++i) {
+ chars[i] = (char) i;
+ }
+ }
+ }
+
+ public void timeDigit(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.digit(ch, 10);
+ }
+ }
+ }
+
+ public void timeGetNumericValue(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.getNumericValue(ch);
+ }
+ }
+ }
+
+ public void timeIsDigit(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isDigit(ch);
+ }
+ }
+ }
+
+ public void timeIsIdentifierIgnorable(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isIdentifierIgnorable(ch);
+ }
+ }
+ }
+
+ public void timeIsJavaIdentifierPart(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isJavaIdentifierPart(ch);
+ }
+ }
+ }
+
+ public void timeIsJavaIdentifierStart(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isJavaIdentifierStart(ch);
+ }
+ }
+ }
+
+ public void timeIsLetter(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isLetter(ch);
+ }
+ }
+ }
+
+ public void timeIsLetterOrDigit(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isLetterOrDigit(ch);
+ }
+ }
+ }
+
+ public void timeIsLowerCase(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isLowerCase(ch);
+ }
+ }
+ }
+
+ public void timeIsSpaceChar(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isSpaceChar(ch);
+ }
+ }
+ }
+
+ public void timeIsUpperCase(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isUpperCase(ch);
+ }
+ }
+ }
+
+ public void timeIsWhitespace(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.isWhitespace(ch);
+ }
+ }
+ }
+
+ public void timeIsNull(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ boolean b = (ch == ' ');
+ }
+ }
+ }
+
+ public void timeToLowerCase(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.toLowerCase(ch);
+ }
+ }
+ }
+
+ public void timeToUpperCase(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ for (char ch = 0; ch < '}'; ++ch) {
+ Character.toUpperCase(ch);
+ }
+ }
+ }
+}
diff --git a/test/com/google/caliper/examples/DoubleToStringBenchmarkSuite.java b/test/com/google/caliper/examples/DoubleToStringBenchmarkSuite.java
deleted file mode 100644
index a5d5234..0000000
--- a/test/com/google/caliper/examples/DoubleToStringBenchmarkSuite.java
+++ /dev/null
@@ -1,77 +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.examples;
-
-import com.google.caliper.Benchmark;
-import com.google.caliper.DefaultBenchmarkSuite;
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-/**
- * Measures the various ways the JDK converts doubles to Strings.
- */
-public class DoubleToStringBenchmarkSuite extends DefaultBenchmarkSuite {
-
- @Param private Double d;
-
- private static Collection<Double> dValues = Arrays.asList(
- Math.PI,
- -0.0d,
- Double.NEGATIVE_INFINITY,
- Double.NaN
- );
-
- class FormatterBenchmark extends Benchmark {
- public Object run(int trials) {
- Double value = d;
- String result = null;
- for (int i = 0; i < trials; i++) {
- result = String.format("%f", value);
- }
- return result;
- }
- }
-
- class ToStringBenchmark extends Benchmark {
- public Object run(int trials) {
- Double value = d;
- String result = null;
- for (int i = 0; i < trials; i++) {
- result = value.toString();
- }
- return result;
- }
- }
-
- class ConcatenationBenchmark extends Benchmark {
- public Object run(int trials) {
- Double value = d;
- String result = null;
- for (int i = 0; i < trials; i++) {
- result = "" + value;
- }
- return result;
- }
- }
-
- public static void main(String[] args) {
- Runner.main(DoubleToStringBenchmarkSuite.class, args);
- }
-}
diff --git a/test/com/google/caliper/examples/EnumSetContainsBenchmarkSuite.java b/test/com/google/caliper/examples/EnumSetContainsBenchmark.java
index da8f0f5..a9f6f2f 100644
--- a/test/com/google/caliper/examples/EnumSetContainsBenchmarkSuite.java
+++ b/test/com/google/caliper/examples/EnumSetContainsBenchmark.java
@@ -16,10 +16,9 @@
package com.google.caliper.examples;
-import com.google.caliper.Benchmark;
-import com.google.caliper.DefaultBenchmarkSuite;
import com.google.caliper.Param;
import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
import java.util.Collection;
import java.util.EnumSet;
@@ -28,11 +27,11 @@ import java.util.Set;
/**
* Measures EnumSet#contains().
*/
-public class EnumSetContainsBenchmarkSuite extends DefaultBenchmarkSuite {
+public class EnumSetContainsBenchmark extends SimpleBenchmark {
@Param private SetMaker setMaker;
- private static Collection<SetMaker> setMakerValues = EnumSet.allOf(SetMaker.class);
+ private static final Collection<SetMaker> setMakerValues = EnumSet.allOf(SetMaker.class);
enum SetMaker {
ENUM_SET {
@@ -85,19 +84,15 @@ public class EnumSetContainsBenchmarkSuite extends DefaultBenchmarkSuite {
this.testValues = setMaker.testValues();
}
- class ContainsBenchmark extends Benchmark {
- @Override public Object run(int trials) throws Exception {
- int count = 0;
- for (int i = 0; i < trials; i++) {
- for (Object value : testValues) {
- count ^= (set.contains(value) ? i : 0);
- }
- }
- return count > 0;
+ public int timeContains(int reps) throws Exception {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ dummy ^= (set.contains(testValues[i % testValues.length]) ? i : 0);
}
+ return dummy;
}
- public static void main(String[] args) {
- Runner.main(EnumSetContainsBenchmarkSuite.class, args);
+ public static void main(String[] args) throws Exception {
+ Runner.main(EnumSetContainsBenchmark.class, args);
}
} \ No newline at end of file
diff --git a/test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java b/test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java
new file mode 100644
index 0000000..2dbcf58
--- /dev/null
+++ b/test/com/google/caliper/examples/ExpensiveObjectsBenchmark.java
@@ -0,0 +1,71 @@
+/*
+ * 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.examples;
+
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+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.
+ */
+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();
+ }
+ }
+}
diff --git a/test/com/google/caliper/examples/FormatterBenchmark.java b/test/com/google/caliper/examples/FormatterBenchmark.java
new file mode 100644
index 0000000..f61f111
--- /dev/null
+++ b/test/com/google/caliper/examples/FormatterBenchmark.java
@@ -0,0 +1,77 @@
+/*
+ * 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.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/test/com/google/caliper/examples/FormatterBenchmarkSuite.java b/test/com/google/caliper/examples/FormatterBenchmarkSuite.java
deleted file mode 100644
index 53dff71..0000000
--- a/test/com/google/caliper/examples/FormatterBenchmarkSuite.java
+++ /dev/null
@@ -1,98 +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.examples;
-
-import com.google.caliper.Benchmark;
-import com.google.caliper.DefaultBenchmarkSuite;
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-
-import java.util.Formatter;
-
-/**
- * Compares Formatter against hand-written StringBuilder code.
- */
-public class FormatterBenchmarkSuite extends DefaultBenchmarkSuite {
-
- class Formatter_NoFormatting extends Benchmark {
- public Object run(int trials) {
- for (int i = 0; i < trials; i++) {
- Formatter f = new Formatter();
- f.format("this is a reasonably short string that doesn't actually need any formatting");
- }
- return null;
- }
- }
-
- class StringBuilder_NoFormatting extends Benchmark {
- public Object run(int trials) {
- for (int i = 0; i < trials; i++) {
- StringBuilder sb = new StringBuilder();
- sb.append("this is a reasonably short string that doesn't actually need any formatting");
- }
- return null;
- }
- }
-
- class Formatter_OneInt extends Benchmark {
- public Object run(int trials) {
- for (int i = 0; i < trials; i++) {
- Formatter f = new Formatter();
- f.format("this is a reasonably short string that has an int %d in it", i);
- }
- return null;
- }
- }
-
- class StringBuilder_OneInt extends Benchmark {
- public Object run(int trials) {
- for (int i = 0; i < trials; i++) {
- StringBuilder sb = new StringBuilder();
- sb.append("this is a reasonably short string that has an int ");
- sb.append(i);
- sb.append(" in it");
- }
- return null;
- }
- }
-
- class Formatter_OneString extends Benchmark {
- public Object run(int trials) {
- for (int i = 0; i < trials; i++) {
- Formatter f = new Formatter();
- f.format("this is a reasonably short string that has a string %s in it", "hello");
- }
- return null;
- }
- }
-
- class StringBuilder_OneString extends Benchmark {
- public Object run(int trials) {
- for (int i = 0; i < trials; i++) {
- StringBuilder sb = new StringBuilder();
- sb.append("this is a reasonably short string that has a string ");
- sb.append("hello");
- sb.append(" in it");
- }
- return null;
- }
- }
-
- public static void main(String[] args) {
- Runner.main(FormatterBenchmarkSuite.class, args);
- }
-}
diff --git a/test/com/google/caliper/examples/IntModBenchmark.java b/test/com/google/caliper/examples/IntModBenchmark.java
new file mode 100644
index 0000000..86e85e7
--- /dev/null
+++ b/test/com/google/caliper/examples/IntModBenchmark.java
@@ -0,0 +1,90 @@
+/*
+ * 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.examples;
+
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Measures several candidate implementations for mod().
+ */
+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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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/test/com/google/caliper/examples/ListIterationBenchmarkSuite.java b/test/com/google/caliper/examples/ListIterationBenchmark.java
index 0ed7197..53bcdf8 100644
--- a/test/com/google/caliper/examples/ListIterationBenchmarkSuite.java
+++ b/test/com/google/caliper/examples/ListIterationBenchmark.java
@@ -16,26 +16,27 @@
package com.google.caliper.examples;
-import com.google.caliper.Benchmark;
-import com.google.caliper.DefaultBenchmarkSuite;
import com.google.caliper.Param;
import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
-import java.util.*;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
/**
* Measures iterating through list elements.
*/
-public class ListIterationBenchmarkSuite extends DefaultBenchmarkSuite {
-
+public class ListIterationBenchmark extends SimpleBenchmark {
@Param private int length;
- private static Collection<Integer> lengthValues = Arrays.asList(0, 10, 100, 1000);
+ private static final Collection<Integer> lengthValues = Arrays.asList(0, 10, 100, 1000);
private List<Object> list;
private Object[] array;
- @Override protected void setUp() throws Exception {
+ @Override protected void setUp() {
array = new Object[length];
for (int i = 0; i < length; i++) {
array[i] = new Object();
@@ -52,31 +53,28 @@ public class ListIterationBenchmarkSuite extends DefaultBenchmarkSuite {
};
}
- class ListIterateBenchmark extends Benchmark {
- @Override public Object run(int trials) throws Exception {
- int count = 0;
- for (int i = 0; i < trials; i++) {
- for (Object value : list) {
- count ^= (value == Boolean.TRUE) ? i : 0;
- }
+ public int timeListIteration(int reps) {
+ int count = 0;
+ for (int i = 0; i < reps; i++) {
+ for (Object value : list) {
+ count ^= value.hashCode(); // prevent overoptimization
}
- return count > 0;
}
+ return count; // ignored
}
- class ArrayIterateBenchmark extends Benchmark {
- @Override public Object run(int trials) throws Exception {
- int count = 0;
- for (int i = 0; i < trials; i++) {
- for (Object value : array) {
- count ^= (value == Boolean.TRUE) ? i : 0;
- }
+ public int timeArrayIteration(int reps) {
+ int count = 0;
+ for (int i = 0; i < reps; i++) {
+ for (Object value : array) {
+ count ^= value.hashCode(); // prevent overoptimization
}
- return count > 0;
}
+ return count; // ignored
}
- public static void main(String[] args) {
- Runner.main(ListIterationBenchmarkSuite.class, args);
+ // 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/test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java b/test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java
new file mode 100644
index 0000000..592acdc
--- /dev/null
+++ b/test/com/google/caliper/examples/PrimitiveDoubleToStringBenchmark.java
@@ -0,0 +1,80 @@
+/*
+ * 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.examples;
+
+import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Measures the various ways the JDK converts primitive doubles to Strings.
+ */
+public class PrimitiveDoubleToStringBenchmark extends SimpleBenchmark {
+
+ @Param private double d;
+
+ private static final Collection<Double> dValues = Arrays.asList(
+ 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/test/com/google/caliper/examples/StringBuilderBenchmark.java b/test/com/google/caliper/examples/StringBuilderBenchmark.java
new file mode 100644
index 0000000..2fa6819
--- /dev/null
+++ b/test/com/google/caliper/examples/StringBuilderBenchmark.java
@@ -0,0 +1,132 @@
+/*
+ * 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.examples;
+
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Tests the performance of various StringBuilder methods.
+ */
+public class StringBuilderBenchmark extends SimpleBenchmark {
+
+ @Param int length;
+ static Collection<Integer> lengthValues = Arrays.asList(1, 10, 100);
+
+ 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);
+ }
+ }
+ }
+}