• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Guava Authors
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.common.math;
18 
19 import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
20 import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
21 import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
22 import static com.google.common.math.MathBenchmarking.randomBigInteger;
23 import static com.google.common.math.MathBenchmarking.randomNonNegativeBigInteger;
24 
25 import com.google.caliper.BeforeExperiment;
26 import com.google.caliper.Benchmark;
27 import com.google.caliper.Param;
28 
29 /**
30  * Benchmarks against the Apache Commons Math utilities.
31  *
32  * <p>Note: the Apache benchmarks are not open sourced to avoid the extra dependency.
33  *
34  * @author Louis Wasserman
35  */
36 public class ApacheBenchmark {
37   private enum Impl {
38     GUAVA {
39       @Override
factorialDouble(int n)40       public double factorialDouble(int n) {
41         return DoubleMath.factorial(n);
42       }
43 
44       @Override
gcdInt(int a, int b)45       public int gcdInt(int a, int b) {
46         return IntMath.gcd(a, b);
47       }
48 
49       @Override
gcdLong(long a, long b)50       public long gcdLong(long a, long b) {
51         return LongMath.gcd(a, b);
52       }
53 
54       @Override
binomialCoefficient(int n, int k)55       public long binomialCoefficient(int n, int k) {
56         return LongMath.binomial(n, k);
57       }
58 
59       @Override
noAddOverflow(int a, int b)60       public boolean noAddOverflow(int a, int b) {
61         try {
62           int unused = IntMath.checkedAdd(a, b);
63           return true;
64         } catch (ArithmeticException e) {
65           return false;
66         }
67       }
68 
69       @Override
noAddOverflow(long a, long b)70       public boolean noAddOverflow(long a, long b) {
71         try {
72           long unused = LongMath.checkedAdd(a, b);
73           return true;
74         } catch (ArithmeticException e) {
75           return false;
76         }
77       }
78 
79       @Override
noMulOverflow(int a, int b)80       public boolean noMulOverflow(int a, int b) {
81         try {
82           int unused = IntMath.checkedMultiply(a, b);
83           return true;
84         } catch (ArithmeticException e) {
85           return false;
86         }
87       }
88 
89       @Override
noMulOverflow(long a, long b)90       public boolean noMulOverflow(long a, long b) {
91         try {
92           long unused = LongMath.checkedMultiply(a, b);
93           return true;
94         } catch (ArithmeticException e) {
95           return false;
96         }
97       }
98     };
99 
factorialDouble(int n)100     public abstract double factorialDouble(int n);
101 
binomialCoefficient(int n, int k)102     public abstract long binomialCoefficient(int n, int k);
103 
gcdInt(int a, int b)104     public abstract int gcdInt(int a, int b);
105 
gcdLong(long a, long b)106     public abstract long gcdLong(long a, long b);
107 
noAddOverflow(int a, int b)108     public abstract boolean noAddOverflow(int a, int b);
109 
noAddOverflow(long a, long b)110     public abstract boolean noAddOverflow(long a, long b);
111 
noMulOverflow(int a, int b)112     public abstract boolean noMulOverflow(int a, int b);
113 
noMulOverflow(long a, long b)114     public abstract boolean noMulOverflow(long a, long b);
115   }
116 
117   private final int[] factorials = new int[ARRAY_SIZE];
118   private final int[][] binomials = new int[ARRAY_SIZE][2];
119   private final int[][] nonnegInt = new int[ARRAY_SIZE][2];
120   private final long[][] nonnegLong = new long[ARRAY_SIZE][2];
121   private final int[][] intsToAdd = new int[ARRAY_SIZE][2];
122   private final int[][] intsToMul = new int[ARRAY_SIZE][2];
123   private final long[][] longsToAdd = new long[ARRAY_SIZE][2];
124   private final long[][] longsToMul = new long[ARRAY_SIZE][2];
125 
126   @Param({"APACHE", "GUAVA"})
127   Impl impl;
128 
129   @BeforeExperiment
setUp()130   void setUp() {
131     for (int i = 0; i < ARRAY_SIZE; i++) {
132       factorials[i] = RANDOM_SOURCE.nextInt(200);
133       for (int j = 0; j < 2; j++) {
134         nonnegInt[i][j] = randomNonNegativeBigInteger(Integer.SIZE - 2).intValue();
135         nonnegLong[i][j] = randomNonNegativeBigInteger(Long.SIZE - 2).longValue();
136       }
137       do {
138         for (int j = 0; j < 2; j++) {
139           intsToAdd[i][j] = randomBigInteger(Integer.SIZE - 2).intValue();
140         }
141       } while (!Impl.GUAVA.noAddOverflow(intsToAdd[i][0], intsToAdd[i][1]));
142       do {
143         for (int j = 0; j < 2; j++) {
144           longsToAdd[i][j] = randomBigInteger(Long.SIZE - 2).longValue();
145         }
146       } while (!Impl.GUAVA.noAddOverflow(longsToAdd[i][0], longsToAdd[i][1]));
147       do {
148         for (int j = 0; j < 2; j++) {
149           intsToMul[i][j] = randomBigInteger(Integer.SIZE - 2).intValue();
150         }
151       } while (!Impl.GUAVA.noMulOverflow(intsToMul[i][0], intsToMul[i][1]));
152       do {
153         for (int j = 0; j < 2; j++) {
154           longsToMul[i][j] = randomBigInteger(Long.SIZE - 2).longValue();
155         }
156       } while (!Impl.GUAVA.noMulOverflow(longsToMul[i][0], longsToMul[i][1]));
157 
158       int k = binomials[i][1] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials.length);
159       binomials[i][0] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials[k] - k) + k;
160     }
161   }
162 
163   @Benchmark
factorialDouble(int reps)164   long factorialDouble(int reps) {
165     long tmp = 0;
166     for (int i = 0; i < reps; i++) {
167       int j = i & ARRAY_MASK;
168       tmp += Double.doubleToRawLongBits(impl.factorialDouble(factorials[j]));
169     }
170     return tmp;
171   }
172 
173   @Benchmark
intGCD(int reps)174   int intGCD(int reps) {
175     int tmp = 0;
176     for (int i = 0; i < reps; i++) {
177       int j = i & ARRAY_MASK;
178       tmp += impl.gcdInt(nonnegInt[j][0], nonnegInt[j][1]);
179     }
180     return tmp;
181   }
182 
183   @Benchmark
longGCD(int reps)184   long longGCD(int reps) {
185     long tmp = 0;
186     for (int i = 0; i < reps; i++) {
187       int j = i & ARRAY_MASK;
188       tmp += impl.gcdLong(nonnegLong[j][0], nonnegLong[j][1]);
189     }
190     return tmp;
191   }
192 
193   @Benchmark
binomialCoefficient(int reps)194   long binomialCoefficient(int reps) {
195     long tmp = 0;
196     for (int i = 0; i < reps; i++) {
197       int j = i & ARRAY_MASK;
198       tmp += impl.binomialCoefficient(binomials[j][0], binomials[j][1]);
199     }
200     return tmp;
201   }
202 
203   @Benchmark
intAddOverflow(int reps)204   int intAddOverflow(int reps) {
205     int tmp = 0;
206     for (int i = 0; i < reps; i++) {
207       int j = i & ARRAY_MASK;
208       if (impl.noAddOverflow(intsToAdd[j][0], intsToAdd[j][1])) {
209         tmp++;
210       }
211     }
212     return tmp;
213   }
214 
215   @Benchmark
longAddOverflow(int reps)216   int longAddOverflow(int reps) {
217     int tmp = 0;
218     for (int i = 0; i < reps; i++) {
219       int j = i & ARRAY_MASK;
220       if (impl.noAddOverflow(longsToAdd[j][0], longsToAdd[j][1])) {
221         tmp++;
222       }
223     }
224     return tmp;
225   }
226 
227   @Benchmark
intMulOverflow(int reps)228   int intMulOverflow(int reps) {
229     int tmp = 0;
230     for (int i = 0; i < reps; i++) {
231       int j = i & ARRAY_MASK;
232       if (impl.noMulOverflow(intsToMul[j][0], intsToMul[j][1])) {
233         tmp++;
234       }
235     }
236     return tmp;
237   }
238 
239   @Benchmark
longMulOverflow(int reps)240   int longMulOverflow(int reps) {
241     int tmp = 0;
242     for (int i = 0; i < reps; i++) {
243       int j = i & ARRAY_MASK;
244       if (impl.noMulOverflow(longsToMul[j][0], longsToMul[j][1])) {
245         tmp++;
246       }
247     }
248     return tmp;
249   }
250 }
251