1 /* 2 * Copyright (C) 2015 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 benchmarks; 18 19 import java.math.BigInteger; 20 import java.util.Random; 21 22 /** 23 * This pretends to measure performance of operations on small BigIntegers. 24 * Given our current implementation, this is really a way to measure performance of 25 * finalization and JNI. 26 * We manually determine the number of iterations so that it should cause total memory 27 * allocation on the order of a few hundred megabytes. Due to BigInteger's reliance on 28 * finalization, these may unfortunately all be kept around at once. 29 */ 30 public class SmallBigIntegerBenchmark { 31 // We allocate about 2 1/3 BigIntegers per iteration. 32 // Assuming 100 bytes/BigInteger, this gives us around 500MB total. 33 static final int NITERS = 2 * 1000 * 1000; 34 static final BigInteger BIG_THREE = BigInteger.valueOf(3); 35 static final BigInteger BIG_FOUR = BigInteger.valueOf(4); 36 37 public static void main(String args[]) { 38 final Random r = new Random(); 39 BigInteger x = new BigInteger(20, r); 40 final long startNanos = System.nanoTime(); 41 long intermediateNanos = 0; 42 for (int i = 0; i < NITERS; ++i) { 43 if (i == NITERS / 100) { 44 intermediateNanos = System.nanoTime(); 45 } 46 // We know this converges, but the compiler doesn't. 47 if (x.and(BigInteger.ONE).equals(BigInteger.ONE)) { 48 x = x.multiply(BIG_THREE).add(BigInteger.ONE); 49 } else { 50 x = x.shiftRight(1); 51 } 52 } 53 if (x.signum() < 0 || x.compareTo(BIG_FOUR) > 0) { 54 throw new AssertionError("Something went horribly wrong."); 55 } 56 final long finalNanos = System.nanoTime(); 57 double firstFewTime = ((double) intermediateNanos - (double) startNanos) / (NITERS / 100); 58 double restTime = ((double) finalNanos - (double) intermediateNanos) / (99 * NITERS / 100); 59 System.out.println("First Few: " + firstFewTime 60 + " nanoseconds per iteration (2.33 BigInteger ops/iter)"); 61 System.out.println("Remainder: " + restTime + " nanoseconds per iteration"); 62 } 63 } 64 65