1 /* 2 * Copyright (C) 2013 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.caliper; 18 19 import static java.lang.annotation.ElementType.METHOD; 20 import static java.lang.annotation.RetentionPolicy.RUNTIME; 21 22 import java.lang.annotation.Retention; 23 import java.lang.annotation.Target; 24 25 /** 26 * Annotation for benchmark methods. To write a benchmark: 27 * 28 * <ol> 29 * <li>Annotate one or more methods with this annotation. 30 * <li>Annotate any fields with {@literal @}{@link Param} that should have parameter values 31 * injected (see {@literal @}{@link Param} for more details) 32 * <li>Optionally use {@link BeforeExperiment} and {@link AfterExperiment} on setup and teardown 33 * methods 34 * </ol> 35 * 36 * <p>Since many benchmarks may execute in a shorter duration than is accurately measured by 37 * available timers, benchmark methods <i>may</i> take either an {@code int} or {@code long} 38 * argument representing a number of repetitions to perform in a given execution. It is critical 39 * that the work done in the benchmark method scale linearly to the number of repetitions. 40 * 41 * <p>Benchmark methods may return any value. It will be ignored. 42 * 43 * <p>This class is instantiated and injected only once per child VM invocation, to measure one 44 * particular combination of parameters. 45 * 46 * <p>For example: <pre> {@code 47 * public final class MyBenchmark { 48 * {@literal @}Param FeatureEnum feature; 49 * {@literal @}Param({"1", "10", "100"}) int size; 50 * private MyObject objectToBenchmark; 51 * 52 * {@literal @}BeforeExperiment void initializeObject() { 53 * objectToBenchmark = new MyObject(size); 54 * } 55 * 56 * {@literal @}Benchmark int foo(int reps) { 57 * MyObject object = objectToBenchmark; // copy to local to avoid field access overhead 58 * int dummy = 0; 59 * for (int i = 0; i < reps; i++) { 60 * dummy += object.foo(feature); 61 * } 62 * // return a dummy value so the JIT compiler doesn't optimize away the entire method. 63 * return dummy; 64 * } 65 * 66 * {@literal @}Benchmark int bar() { 67 * // benchmark another operation of MyObject that doesn't require a reps parameter 68 * } 69 * } 70 * </pre> 71 * 72 * <p>The benchmark class MyBenchmark has two benchmark methods ({@code foo} and {@code bar}) and 73 * two {@link Param Params} ({@code feature} and {@code size}). For each experiment performed by 74 * Caliper (e.g. {@code foo} with {@code feature == FeatureEnum.A} and {@code size == 100}), 75 * {@code initializeObject} will be called exactly once, but {@code foo} may be called many times. 76 */ 77 @Target(METHOD) 78 @Retention(RUNTIME) 79 public @interface Benchmark {} 80