1 /* 2 * Copyright (C) 2012 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 examples; 18 19 import com.google.caliper.BeforeExperiment; 20 import com.google.caliper.Benchmark; 21 import com.google.caliper.Param; 22 import com.google.caliper.api.SkipThisScenarioException; 23 24 import java.util.Random; 25 26 /** 27 * Benchmarks the overhead created by using varargs instead of parameter expansion. 28 * 29 * @author gak@google.com (Gregory Kick) 30 */ 31 public final class VarargsBenchmark { 32 enum Strategy { 33 VARARGS { one(long a)34 @Override long one(long a) { 35 return varargs(a); 36 } 37 two(long a, long b)38 @Override long two(long a, long b) { 39 return varargs(a, b); 40 } 41 three(long a, long b, long c)42 @Override long three(long a, long b, long c) { 43 return varargs(a, b, c); 44 } 45 four(long a, long b, long c, long d)46 @Override long four(long a, long b, long c, long d) { 47 return varargs(a, b, c, d); 48 } 49 five(long a, long b, long c, long d, long e)50 @Override long five(long a, long b, long c, long d, long e) { 51 return varargs(a, b, c, d); 52 } 53 six(long a, long b, long c, long d, long e, long f)54 @Override long six(long a, long b, long c, long d, long e, long f) { 55 return varargs(a, b, c, d, e, f); 56 }}, 57 EXPANSION { one(long a)58 @Override long one(long a) { 59 return VarargsBenchmark.one(a); 60 } 61 two(long a, long b)62 @Override long two(long a, long b) { 63 return VarargsBenchmark.two(a, b); 64 } 65 three(long a, long b, long c)66 @Override long three(long a, long b, long c) { 67 return VarargsBenchmark.three(a, b, c); 68 } 69 four(long a, long b, long c, long d)70 @Override long four(long a, long b, long c, long d) { 71 return VarargsBenchmark.four(a, b, c, d); 72 } 73 five(long a, long b, long c, long d, long e)74 @Override long five(long a, long b, long c, long d, long e) { 75 return VarargsBenchmark.five(a, b, c, d, e); 76 } 77 six(long a, long b, long c, long d, long e, long f)78 @Override long six(long a, long b, long c, long d, long e, long f) { 79 return VarargsBenchmark.six(a, b, c, d, e, f); 80 } 81 }; 82 one(long a)83 abstract long one(long a); 84 two(long a, long b)85 abstract long two(long a, long b); 86 three(long a, long b, long c)87 abstract long three(long a, long b, long c); 88 four(long a, long b, long c, long d)89 abstract long four(long a, long b, long c, long d); 90 five(long a, long b, long c, long d, long e)91 abstract long five(long a, long b, long c, long d, long e); 92 six(long a, long b, long c, long d, long e, long f)93 abstract long six(long a, long b, long c, long d, long e, long f); 94 } 95 varargs(long... longs)96 private static long varargs(long... longs) { 97 long result = 0; 98 for (long i : longs) { 99 result ^= i; 100 } 101 return result; 102 } 103 one(long a)104 private static long one(long a) { 105 return a; 106 } 107 two(long a, long b)108 private static long two(long a, long b) { 109 return a ^ b; 110 } 111 three(long a, long b, long c)112 private static long three(long a, long b, long c) { 113 return a ^ b ^ c; 114 } 115 four(long a, long b, long c, long d)116 private static long four(long a, long b, long c, long d) { 117 return a ^ b ^ c ^ d; 118 } 119 five(long a, long b, long c, long d, long e)120 private static long five(long a, long b, long c, long d, long e) { 121 return a ^ b ^ c ^ d ^ e; 122 } 123 six(long a, long b, long c, long d, long e, long f)124 private static long six(long a, long b, long c, long d, long e, long f) { 125 return a ^ b ^ c ^ d ^ e ^ f; 126 } 127 128 @Param private Strategy strategy; 129 @Param({"1", "2", "3", "4", "5", "6"}) private int arguments; 130 131 private long[] data = new long[2048]; 132 setUp()133 @BeforeExperiment void setUp() { 134 Random random = new Random(); 135 for (int i = 0; i < data.length; i++) { 136 data[i] = random.nextLong(); 137 } 138 } 139 invocation(int reps)140 @Benchmark long invocation(int reps) { 141 switch (arguments) { 142 case 1: 143 return oneArgument(reps); 144 case 2: 145 return twoArguments(reps); 146 case 3: 147 return threeArguments(reps); 148 case 4: 149 return fourArguments(reps); 150 case 5: 151 return fiveArguments(reps); 152 case 6: 153 return sixArguments(reps); 154 default: 155 throw new SkipThisScenarioException(); 156 } 157 } 158 oneArgument(int reps)159 private long oneArgument(int reps) { 160 long dummy = 0; 161 long[] data = this.data; 162 int dataLength = data.length; 163 for (int i = 0; i < reps; i++) { 164 dummy += strategy.one(data[i % dataLength]); 165 } 166 return dummy; 167 } 168 twoArguments(int reps)169 private long twoArguments(int reps) { 170 long dummy = 0; 171 long[] data = this.data; 172 int dataLength = data.length; 173 for (int i = 0; i < reps; i++) { 174 dummy += strategy.two(data[i % dataLength], data[(i + 1) % dataLength]); 175 } 176 return dummy; 177 } 178 threeArguments(int reps)179 private long threeArguments(int reps) { 180 long dummy = 0; 181 long[] data = this.data; 182 int dataLength = data.length; 183 for (int i = 0; i < reps; i++) { 184 dummy += strategy.three( 185 data[i % dataLength], 186 data[(i + 1) % dataLength], 187 data[(i + 2) % dataLength]); 188 } 189 return dummy; 190 } 191 fourArguments(int reps)192 private long fourArguments(int reps) { 193 long dummy = 0; 194 long[] data = this.data; 195 int dataLength = data.length; 196 for (int i = 0; i < reps; i++) { 197 dummy += strategy.four( 198 data[i % dataLength], 199 data[(i + 1) % dataLength], 200 data[(i + 2) % dataLength], 201 data[(i + 3) % dataLength]); 202 } 203 return dummy; 204 } 205 fiveArguments(int reps)206 private long fiveArguments(int reps) { 207 long dummy = 0; 208 long[] data = this.data; 209 int dataLength = data.length; 210 for (int i = 0; i < reps; i++) { 211 dummy += strategy.five( 212 data[i % dataLength], 213 data[(i + 1) % dataLength], 214 data[(i + 2) % dataLength], 215 data[(i + 3) % dataLength], 216 data[(i + 4) % dataLength]); 217 } 218 return dummy; 219 } 220 sixArguments(int reps)221 private long sixArguments(int reps) { 222 long dummy = 0; 223 long[] data = this.data; 224 int dataLength = data.length; 225 for (int i = 0; i < reps; i++) { 226 dummy += strategy.six( 227 data[i % dataLength], 228 data[(i + 1) % dataLength], 229 data[(i + 2) % dataLength], 230 data[(i + 3) % dataLength], 231 data[(i + 4) % dataLength], 232 data[(i + 5) % dataLength]); 233 } 234 return dummy; 235 } 236 } 237