1 /*
   2  * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 /*
  24  * To change this template, choose Tools | Templates
  25  * and open the template in the editor.
  26  */
  27 package org.openjdk.bench.java.math;
  28 
  29 import org.openjdk.jmh.annotations.Benchmark;
  30 import org.openjdk.jmh.annotations.BenchmarkMode;
  31 import org.openjdk.jmh.annotations.Mode;
  32 import org.openjdk.jmh.annotations.OperationsPerInvocation;
  33 import org.openjdk.jmh.annotations.OutputTimeUnit;
  34 import org.openjdk.jmh.annotations.Scope;
  35 import org.openjdk.jmh.annotations.Setup;
  36 import org.openjdk.jmh.annotations.State;
  37 import org.openjdk.jmh.infra.Blackhole;
  38 
  39 import java.math.BigInteger;
  40 import java.util.Random;
  41 import java.util.concurrent.TimeUnit;
  42 
  43 @BenchmarkMode(Mode.AverageTime)
  44 @OutputTimeUnit(TimeUnit.NANOSECONDS)
  45 @State(Scope.Thread)
  46 public class BigIntegers {
  47 
  48     private BigInteger[] hugeArray, largeArray, smallArray, shiftArray;
  49     public String[] dummyStringArray;
  50     public Object[] dummyArr;
  51     private static final int TESTSIZE = 1000;
  52 
  53     @Setup
  54     public void setup() {
  55         Random r = new Random(1123);
  56         int numbits = r.nextInt(16384);
  57 
  58         hugeArray = new BigInteger[TESTSIZE]; /*
  59          * Huge numbers larger than
  60          * MAX_LONG
  61          */
  62         largeArray = new BigInteger[TESTSIZE]; /*
  63          * Large numbers less than
  64          * MAX_LONG but larger than
  65          * MAX_INT
  66          */
  67         smallArray = new BigInteger[TESTSIZE]; /*
  68          * Small number less than
  69          * MAX_INT
  70          */
  71         shiftArray = new BigInteger[TESTSIZE]; /*
  72          * Each array entry is atmost 16k bits
  73          * in size
  74          */
  75 
  76         dummyStringArray = new String[TESTSIZE];
  77         dummyArr = new Object[TESTSIZE];
  78 
  79         for (int i = 0; i < TESTSIZE; i++) {
  80             int value = Math.abs(r.nextInt());
  81 
  82             hugeArray[i] = new BigInteger("" + ((long) value + (long) Integer.MAX_VALUE)
  83                     + ((long) value + (long) Integer.MAX_VALUE));
  84             largeArray[i] = new BigInteger("" + ((long) value + (long) Integer.MAX_VALUE));
  85             smallArray[i] = new BigInteger("" + ((long) value / 1000));
  86             shiftArray[i] = new BigInteger(numbits, r);
  87         }
  88     }
  89 
  90     /** Test BigInteger.toString() with huge numbers larger than MAX_LONG */
  91     @Benchmark
  92     @OperationsPerInvocation(TESTSIZE)
  93     public void testHugeToString(Blackhole bh) {
  94         for (BigInteger s : hugeArray) {
  95             bh.consume(s.toString());
  96         }
  97     }
  98 
  99     /** Test BigInteger.toString() with large numbers less than MAX_LONG but larger than MAX_INT */
 100     @Benchmark
 101     @OperationsPerInvocation(TESTSIZE)
 102     public void testLargeToString(Blackhole bh) {
 103         for (BigInteger s : largeArray) {
 104             bh.consume(s.toString());
 105         }
 106     }
 107 
 108     /** Test BigInteger.toString() with small numbers less than MAX_INT */
 109     @Benchmark
 110     @OperationsPerInvocation(TESTSIZE)
 111     public void testSmallToString(Blackhole bh) {
 112         for (BigInteger s : smallArray) {
 113             bh.consume(s.toString());
 114         }
 115     }
 116 
 117     /** Invokes the multiply method of BigInteger with various different values. */
 118     @Benchmark
 119     @OperationsPerInvocation(TESTSIZE)
 120     public void testMultiply(Blackhole bh) {
 121         BigInteger tmp = null;
 122         for (BigInteger s : hugeArray) {
 123             if (tmp == null) {
 124                 tmp = s;
 125                 continue;
 126             }
 127             tmp = tmp.multiply(s);
 128         }
 129         bh.consume(tmp);
 130     }
 131 
 132     /** Invokes the multiply method of BigInteger with various different values. */
 133     @Benchmark
 134     @OperationsPerInvocation(TESTSIZE)
 135     public void testAdd(Blackhole bh) {
 136         BigInteger tmp = null;
 137         for (BigInteger s : hugeArray) {
 138             if (tmp == null) {
 139                 tmp = s;
 140                 continue;
 141             }
 142             tmp = tmp.add(s);
 143         }
 144         bh.consume(tmp);
 145     }
 146 
 147     /** Invokes the shiftLeft method of BigInteger with different values. */
 148     @Benchmark
 149     @OperationsPerInvocation(TESTSIZE)
 150     public void testLeftShift(Blackhole bh) {
 151         Random rand = new Random();
 152         int shift = rand.nextInt(30) + 1;
 153         BigInteger tmp = null;
 154         for (BigInteger s : shiftArray) {
 155             if (tmp == null) {
 156                 tmp = s;
 157                 continue;
 158             }
 159             tmp = tmp.shiftLeft(shift);
 160         }
 161         bh.consume(tmp);
 162     }
 163 
 164     /** Invokes the shiftRight method of BigInteger with different values. */
 165     @Benchmark
 166     @OperationsPerInvocation(TESTSIZE)
 167     public void testRightShift(Blackhole bh) {
 168         Random rand = new Random();
 169         int shift = rand.nextInt(30) + 1;
 170         BigInteger tmp = null;
 171         for (BigInteger s : shiftArray) {
 172             if (tmp == null) {
 173                 tmp = s;
 174                 continue;
 175             }
 176             tmp = tmp.shiftRight(shift);
 177         }
 178         bh.consume(tmp);
 179     }
 180 }